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@1
|
12 EventLogger eventLogger;
|
rt300@29
|
13
|
rt300@8
|
14 //---------------------------------------------------------------------------
|
rt300@1
|
15 EventLogger::EventLogger(){
|
rt300@14
|
16 //QuestionnaireViewController * questionnaireViewController;
|
rt300@8
|
17
|
rt300@25
|
18 consentGiven = true; // unless told otherwise by introView
|
rt300@8
|
19 loggingEnabled = true;
|
rt300@22
|
20 serverConnectionOK = false;
|
rt300@22
|
21 questionnaireCompleted = false;
|
rt300@22
|
22 questionnaireUploaded = false;
|
rt300@27
|
23 currentHTTPRequestID = -1;
|
rt300@27
|
24 logUploadInProgress = false;
|
rt300@22
|
25 ofxiPhoneDeviceType iOSdeviceType = ofxiPhoneGetDeviceType();
|
rt300@22
|
26 cout << "Device: " << iOSdeviceType << '\n';
|
rt300@22
|
27
|
rt300@25
|
28 nextUploadQty = UPLOAD_CHUNK_SIZE; // amount of data uploaded is always more than UPLOAD_CHUNK_SIZE events
|
rt300@27
|
29
|
rt300@8
|
30 }
|
rt300@8
|
31 //---------------------------------------------------------------------------
|
rt300@24
|
32 // draw() - show path of last N scroll events - can be scrubbed along?
|
rt300@24
|
33 //
|
rt300@24
|
34 //---------------------------------------------------------------------------
|
rt300@29
|
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@25
|
43 logEvent(APP_STARTED);
|
rt300@29
|
44
|
rt300@29
|
45 stringstream r;
|
rt300@29
|
46 r << LOGGING_SERVER_URL << "testConnection?jsontext=" << "{\"test\":\"test\"}&Content-Length=456";
|
rt300@29
|
47
|
rt300@29
|
48 NSString *urlstring;
|
rt300@29
|
49 urlstring = @"http://127.0.0.1:8080/testservice/testConnection?jsontext={\"objc post\":\"obj c post\"}";
|
rt300@29
|
50 serverComms = [[ServerComms alloc] init];
|
rt300@29
|
51 [serverComms postRequest:urlstring];
|
rt300@29
|
52
|
rt300@29
|
53
|
rt300@29
|
54 urlstring = nil;
|
rt300@8
|
55 }
|
rt300@29
|
56
|
rt300@8
|
57 //---------------------------------------------------------------------------
|
rt300@28
|
58 void EventLogger::questionnaireAnswersObtained(vector<int> answers, const char* userComments){
|
rt300@22
|
59
|
rt300@22
|
60 questionnaireCompleted = true;
|
rt300@22
|
61 questionnaireAnswers = answers;
|
rt300@28
|
62 questionnaireComments = userComments;
|
rt300@22
|
63 uploadQuestionnaire();
|
rt300@22
|
64
|
rt300@22
|
65 }
|
rt300@22
|
66 //---------------------------------------------------------------------------
|
rt300@27
|
67 void EventLogger::uploadQuestionnaire(){
|
rt300@22
|
68 // show indicator
|
rt300@22
|
69 cout << "^^^^^^^^ UPLOADING QUESTIONNAIRE ^^^^^^^^ \n";
|
rt300@22
|
70
|
rt300@27
|
71 sendToServer("questionnaire", questionnaireToJson(), true);
|
rt300@27
|
72
|
rt300@22
|
73 }
|
rt300@22
|
74 //---------------------------------------------------------------------------
|
rt300@27
|
75 bool EventLogger::sendToServer(string functionName, Json::Value jsonData, bool async = false){
|
rt300@22
|
76 bool sent;
|
rt300@29
|
77 stringstream request;
|
rt300@22
|
78
|
rt300@29
|
79 request << LOGGING_SERVER_URL << functionName << "?jsontext=";
|
rt300@29
|
80 /*
|
rt300@22
|
81 if(functionName == "testConnection"){
|
rt300@22
|
82 request = "http://127.0.0.1:8080/testservice/testConnection?jsontext=";
|
rt300@22
|
83 }else if(functionName == "questionnaire"){
|
rt300@22
|
84 request = "http://127.0.0.1:8080/testservice/questionnaire?jsontext=";
|
rt300@22
|
85 }else if(functionName == "eventlog"){
|
rt300@22
|
86 request = "http://127.0.0.1:8080/testservice/eventlog?jsontext=";
|
rt300@22
|
87 }
|
rt300@29
|
88 */
|
rt300@22
|
89 Json::FastWriter writer;
|
rt300@22
|
90 string jsontext = writer.write( jsonData );
|
rt300@22
|
91
|
rt300@27
|
92 // remove newline
|
rt300@22
|
93 if (!jsontext.empty() && jsontext[jsontext.length()-1] == '\n') {
|
rt300@22
|
94 jsontext.erase(jsontext.length()-1);
|
rt300@22
|
95 }
|
rt300@22
|
96
|
rt300@29
|
97 request << jsontext;
|
rt300@29
|
98
|
rt300@29
|
99 cout << request.str();
|
rt300@27
|
100
|
rt300@27
|
101 if(!async){
|
rt300@27
|
102 ofURLFileLoader fileLoader;
|
rt300@27
|
103 ofHttpResponse resp;
|
rt300@29
|
104 resp = fileLoader.get(request.str());
|
rt300@22
|
105
|
rt300@27
|
106 cout << "HTTP STATUS " << resp.status << "\n";
|
rt300@27
|
107 cout << "HTTP ERROR " << resp.error << "\n";
|
rt300@27
|
108 cout << "HTTP DATA " << resp.data << "\n"; // ofBuffer
|
rt300@27
|
109
|
rt300@27
|
110 stringstream response;
|
rt300@27
|
111 response << resp.data;
|
rt300@27
|
112
|
rt300@27
|
113 if (resp.status == 200){
|
rt300@27
|
114 if(response.str() == "OK"){
|
rt300@27
|
115
|
rt300@27
|
116 sent = true;
|
rt300@27
|
117 }else{
|
rt300@27
|
118 // not ok
|
rt300@27
|
119 // problem serverside
|
rt300@27
|
120 sent = false;
|
rt300@27
|
121 }
|
rt300@27
|
122 }else{
|
rt300@27
|
123
|
rt300@27
|
124 sent = false;
|
rt300@27
|
125 // SHOW AN ALERT TO USER?
|
rt300@27
|
126 }
|
rt300@27
|
127
|
rt300@27
|
128 return sent;
|
rt300@27
|
129 }else{ // async
|
rt300@27
|
130 ofURLFileLoader fileLoader;
|
rt300@29
|
131 currentHTTPRequestID = ofLoadURLAsync(request.str(), functionName);
|
rt300@27
|
132 ofRegisterURLNotification(this);
|
rt300@27
|
133
|
rt300@27
|
134 return true; // ???
|
rt300@27
|
135 }
|
rt300@27
|
136 }
|
rt300@27
|
137 //-----------------------------
|
rt300@27
|
138 void EventLogger::urlResponse(ofHttpResponse & response){
|
rt300@27
|
139 cout << "gotHTTPRequestStatus\n";
|
rt300@27
|
140 cout << "HTTP REQUEST NAME " << response.request.name << "\n";
|
rt300@27
|
141 cout << "HTTP STATUS " << response.status << "\n";
|
rt300@27
|
142 cout << "HTTP ERROR " << response.error << "\n";
|
rt300@27
|
143 cout << "HTTP DATA " << response.data << "\n"; // ofBuffer
|
rt300@9
|
144
|
rt300@27
|
145 bool sent;
|
rt300@27
|
146 stringstream respStr;
|
rt300@27
|
147 respStr << response.data;
|
rt300@22
|
148
|
rt300@27
|
149 if (response.status == 200){
|
rt300@27
|
150 if(respStr.str() == "OK"){
|
rt300@22
|
151
|
rt300@22
|
152 sent = true;
|
rt300@22
|
153 }else{
|
rt300@22
|
154 // not ok
|
rt300@22
|
155 // problem serverside
|
rt300@22
|
156 sent = false;
|
rt300@22
|
157 }
|
rt300@9
|
158 }else{
|
rt300@22
|
159
|
rt300@22
|
160 sent = false;
|
rt300@9
|
161 // SHOW AN ALERT TO USER?
|
rt300@9
|
162 }
|
rt300@27
|
163
|
rt300@27
|
164 // now do request specific stuff
|
rt300@27
|
165 if(response.request.name == "eventlog"){
|
rt300@27
|
166 if(!sent){
|
rt300@27
|
167 // try later
|
rt300@27
|
168 nextUploadQty += UPLOAD_CHUNK_SIZE;
|
rt300@27
|
169 }else{
|
rt300@27
|
170
|
rt300@27
|
171 // if success - clear memory
|
rt300@27
|
172 theEvents.clear();
|
rt300@27
|
173 cout << "UPLOAD SUCCESS\n";
|
rt300@27
|
174 nextUploadNumber++;
|
rt300@27
|
175 }
|
rt300@27
|
176 logUploadInProgress = false;
|
rt300@27
|
177 }else if(response.request.name == "questionnaire"){
|
rt300@27
|
178 if(sent){
|
rt300@27
|
179 questionnaireUploaded = true;
|
rt300@27
|
180 }else{
|
rt300@27
|
181 questionnaireUploaded = false; // will try next time... when?
|
rt300@27
|
182 }
|
rt300@27
|
183 }else if(response.request.name == "testConnection"){
|
rt300@27
|
184
|
rt300@27
|
185 if (sent){
|
rt300@27
|
186 cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n";
|
rt300@27
|
187 serverConnectionOK = true;
|
rt300@27
|
188 }else{
|
rt300@28
|
189 serverConnectionOK = false;
|
rt300@27
|
190 cout << "server connection ERROR \n";
|
rt300@27
|
191 }
|
rt300@27
|
192 }
|
rt300@27
|
193
|
rt300@22
|
194 }
|
rt300@22
|
195 //---------------------------------------------------------------------------
|
rt300@22
|
196 bool EventLogger::testConnection(){
|
rt300@22
|
197 Json::Value root;
|
rt300@29
|
198 root["x"] = "y";
|
rt300@22
|
199
|
rt300@22
|
200
|
rt300@27
|
201 sendToServer("testConnection", root, true);
|
rt300@27
|
202
|
rt300@9
|
203 }
|
rt300@9
|
204 //---------------------------------------------------------------------------
|
rt300@28
|
205 // this reads the persistent log file , checks if we've used the app before and
|
rt300@28
|
206 // if we've answered questionnaire or not
|
rt300@8
|
207 void EventLogger::readJsonToLog(const string &jsonFile){
|
rt300@8
|
208 Json::Value root;
|
rt300@8
|
209 Json::Reader reader;
|
rt300@5
|
210
|
rt300@5
|
211
|
rt300@8
|
212 ifstream theFile(jsonFile.c_str());
|
rt300@8
|
213 stringstream fileText;
|
rt300@8
|
214 string line;
|
rt300@8
|
215 if(!theFile){
|
rt300@8
|
216
|
rt300@8
|
217 firstEverAppOpen();
|
rt300@8
|
218
|
rt300@8
|
219 return;
|
rt300@8
|
220 }else{
|
rt300@8
|
221 while(theFile){
|
rt300@8
|
222 theFile >> line;
|
rt300@9
|
223 // cout << line; // lots!!!!
|
rt300@8
|
224 fileText << line;
|
rt300@8
|
225 }
|
rt300@8
|
226 theFile.close();
|
rt300@8
|
227 }
|
rt300@8
|
228
|
rt300@9
|
229 cout << "size of log JSON string:" << fileText.str().length() << "BYTES \n";
|
rt300@9
|
230
|
rt300@8
|
231 bool parsingSuccessful = reader.parse( fileText.str(), root );
|
rt300@8
|
232
|
rt300@8
|
233 if ( !parsingSuccessful )
|
rt300@8
|
234 {
|
rt300@8
|
235 // report to the user the failure and their locations in the document.
|
rt300@22
|
236 std::cout << "Failed to parse event log JSON: \n"
|
rt300@8
|
237 << reader.getFormattedErrorMessages();
|
rt300@8
|
238 return;
|
rt300@8
|
239 }
|
rt300@8
|
240
|
rt300@8
|
241 // now put user deets into variables
|
rt300@8
|
242 userName = root["userName"].asString();
|
rt300@8
|
243 deviceID = root["deviceID"].asLargestInt();
|
rt300@25
|
244 nextUploadNumber = root["uploadNumber"].asInt();
|
rt300@25
|
245 savedInteractionTime = root["savedInteractionTime"].asLargestInt();
|
rt300@22
|
246 questionnaireCompleted = root["questionnaireCompleted"].asBool();
|
rt300@22
|
247 questionnaireUploaded = root["questionnaireUploaded"].asBool();
|
rt300@28
|
248 interfaceOrder = root["interfaceOrder"].asInt();
|
rt300@22
|
249
|
rt300@22
|
250 if(questionnaireCompleted && !questionnaireUploaded){
|
rt300@22
|
251 // then read it in and upload it
|
rt300@28
|
252 Json::Value JQ = root["questionnaire"];
|
rt300@28
|
253 Json::Value JArray = JQ["qAnswers"];
|
rt300@22
|
254 if(JArray.size() < 2){
|
rt300@22
|
255 cout << "Error - status of questionnaire is wierd\n";
|
rt300@22
|
256 }
|
rt300@22
|
257 for ( unsigned int i = 0; i < JArray.size(); i++ )
|
rt300@22
|
258 {
|
rt300@28
|
259 questionnaireAnswers.push_back(JArray[i].asInt());
|
rt300@22
|
260 }
|
rt300@28
|
261 questionnaireComments = JQ["comments"].toStyledString();
|
rt300@22
|
262 uploadQuestionnaire();
|
rt300@22
|
263 }
|
rt300@8
|
264
|
rt300@8
|
265 // check for unuploaded evts
|
rt300@8
|
266 const Json::Value jlogs = root["events"];
|
rt300@8
|
267
|
rt300@8
|
268 for ( int index = 0; index < jlogs.size(); ++index ) theEvents.push_back(lEvent(jlogs[index]));
|
rt300@27
|
269 if(theEvents.size() > nextUploadQty && ! logUploadInProgress){
|
rt300@8
|
270 //try to upload
|
rt300@27
|
271 uploadEventLog(true);
|
rt300@8
|
272 }
|
rt300@8
|
273 // TODO if the total interaction time is greater than a certain amount && no questions answered - questionnaire time!
|
rt300@25
|
274 cout << "Total interaction time: " << savedInteractionTime << '\n';
|
rt300@28
|
275
|
rt300@29
|
276 //timer.setInteractionTime(savedInteractionTime);
|
rt300@29
|
277 //timer.setOrderFromPrevious(interfaceOrder);
|
rt300@8
|
278
|
rt300@9
|
279 }
|
rt300@9
|
280
|
rt300@9
|
281
|
rt300@9
|
282 //---------------------------------------------------------------------------
|
rt300@9
|
283
|
rt300@27
|
284 bool EventLogger::uploadEventLog(bool async){
|
rt300@28
|
285
|
rt300@22
|
286 // show indicator
|
rt300@27
|
287 logUploadInProgress = true;
|
rt300@25
|
288 cout << "^^^^^^^^ ATTEMPTING TO UPLOAD " << theEvents.size() << " EVENTS ^^^^^^^^ .\n";
|
rt300@27
|
289 if(!async){
|
rt300@27
|
290 bool success = sendToServer("eventlog", logsToJson(), async);
|
rt300@27
|
291 if(!success){
|
rt300@29
|
292 // try later : NOPE has maximum size
|
rt300@27
|
293 nextUploadQty += UPLOAD_CHUNK_SIZE;
|
rt300@27
|
294 }else{
|
rt300@27
|
295
|
rt300@27
|
296 // if success - clear memory
|
rt300@27
|
297 theEvents.clear();
|
rt300@27
|
298 cout << "UPLOAD SUCCESS\n";
|
rt300@27
|
299 nextUploadNumber++;
|
rt300@27
|
300 }
|
rt300@27
|
301 logUploadInProgress = false;
|
rt300@27
|
302 return success;
|
rt300@9
|
303 }else{
|
rt300@27
|
304 sendToServer("eventlog", logsToJson(), async);
|
rt300@9
|
305 }
|
rt300@1
|
306 }
|
rt300@8
|
307 //----------------------------------------------------------------------------
|
rt300@27
|
308
|
rt300@27
|
309 //----------------------------------------------------------------------------
|
rt300@9
|
310 //void EventLogger::deleteLogFile(){
|
rt300@8
|
311
|
rt300@8
|
312 //---------------------------------------------------------------------------
|
rt300@8
|
313
|
rt300@8
|
314 void EventLogger::firstEverAppOpen(){
|
rt300@25
|
315 cout<<"no event log file - first APP open\n";
|
rt300@25
|
316 nextUploadNumber = 0;
|
rt300@8
|
317 deviceID = ofGetSystemTimeMicros();
|
rt300@25
|
318 savedInteractionTime = 0;
|
rt300@22
|
319 questionnaireCompleted = false;
|
rt300@22
|
320 questionnaireUploaded = false;
|
rt300@8
|
321
|
rt300@24
|
322 ((testApp *)ofGetAppPtr())->showIntro();
|
rt300@25
|
323 consentGiven = false;
|
rt300@8
|
324
|
rt300@8
|
325 }
|
rt300@28
|
326 //---------------------------------------------------------------------------
|
rt300@28
|
327 // only called when doing supervised tests
|
rt300@27
|
328 void EventLogger::newUser(){
|
rt300@27
|
329 cout<<"setup new user\n";
|
rt300@29
|
330 deleteLogs();
|
rt300@27
|
331 nextUploadNumber = 0;
|
rt300@27
|
332 deviceID = ofGetSystemTimeMicros();
|
rt300@27
|
333 savedInteractionTime = 0;
|
rt300@28
|
334 totalInteractionTime = 0;
|
rt300@28
|
335 sessionStartTime = ofGetSystemTime();
|
rt300@27
|
336 questionnaireCompleted = false;
|
rt300@29
|
337 questionnaireUploaded = false;
|
rt300@29
|
338
|
rt300@29
|
339 ((testApp *)ofGetAppPtr())->showIntro();
|
rt300@27
|
340
|
rt300@27
|
341 }
|
rt300@8
|
342 //---------------------------------------------------------------------------
|
rt300@8
|
343 // called from alertView OK in iViewController
|
rt300@8
|
344 void EventLogger::setUsername(const char *u){
|
rt300@8
|
345 userName = u;
|
rt300@28
|
346 // start interaction clock
|
rt300@29
|
347
|
rt300@29
|
348 //timer.startInteractionClock();
|
rt300@29
|
349 [((testApp *)ofGetAppPtr())->tsc startTimer];
|
rt300@28
|
350 }
|
rt300@28
|
351 //---------------------------------------------------------------------------
|
rt300@28
|
352 void EventLogger::thinnedLogEvent(lEvent newEvent){
|
rt300@28
|
353 static lEvent previousEvent(APP_STARTED); // initialised as whatever. hopefully won't log
|
rt300@28
|
354 static int eventCounter = 0;
|
rt300@28
|
355
|
rt300@28
|
356 // if first event then log it. it won't be, but still.
|
rt300@28
|
357 if(theEvents.size() == 0){
|
rt300@28
|
358 theEvents.push_back(newEvent);
|
rt300@28
|
359 previousEvent = newEvent;
|
rt300@28
|
360 return;
|
rt300@28
|
361 }
|
rt300@28
|
362
|
rt300@28
|
363 // if previous event is more than 300ms ago, or event type has changed, log both of them
|
rt300@28
|
364 int gap = newEvent.eventTime - previousEvent.eventTime;
|
rt300@28
|
365 if(gap > 300 || newEvent.eventType != previousEvent.eventType){
|
rt300@28
|
366 // if prev event not logged, log it
|
rt300@28
|
367 if((*theEvents.end()).eventTime != previousEvent.eventTime){
|
rt300@28
|
368 theEvents.push_back(previousEvent);
|
rt300@28
|
369 }
|
rt300@28
|
370 theEvents.push_back(newEvent);
|
rt300@7
|
371
|
rt300@28
|
372 }
|
rt300@28
|
373
|
rt300@28
|
374 // otherwise only record every Nth event
|
rt300@28
|
375 if(eventCounter >= EVENT_THIN_FACTOR){
|
rt300@28
|
376 theEvents.push_back(newEvent);
|
rt300@28
|
377 eventCounter = 0;
|
rt300@28
|
378
|
rt300@28
|
379 }
|
rt300@28
|
380 eventCounter++;
|
rt300@28
|
381 previousEvent = newEvent;
|
rt300@7
|
382 }
|
rt300@8
|
383 //---------------------------------------------------------------------------
|
rt300@5
|
384 void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){
|
rt300@3
|
385 //cout << "log: " << evtType << "\n";
|
rt300@1
|
386
|
rt300@1
|
387 // scroll has 2 double coords
|
rt300@1
|
388 // zoom has 1 double scale
|
rt300@1
|
389 // save preset has 2 coords
|
rt300@1
|
390 // switch view has view type
|
rt300@9
|
391 // slider change has int slider index and 1 float value
|
rt300@1
|
392
|
rt300@4
|
393 // get time for key index
|
rt300@4
|
394
|
rt300@5
|
395 // thinFactor
|
rt300@5
|
396 if(!loggingEnabled) return;
|
rt300@4
|
397 switch ( evtType ) {
|
rt300@28
|
398 // data thinning here
|
rt300@28
|
399 case SCROLL:
|
rt300@28
|
400 thinnedLogEvent(lEvent(evtType,centre.x,centre.y));
|
rt300@28
|
401 break;
|
rt300@28
|
402 case ZOOM:
|
rt300@28
|
403 thinnedLogEvent(lEvent(evtType,scale));
|
rt300@28
|
404 break;
|
rt300@28
|
405 case CHANGE_SLIDER:
|
rt300@28
|
406 thinnedLogEvent(lEvent(evtType,sliderVal , 0.0 , sliderID));
|
rt300@28
|
407 break;
|
rt300@29
|
408 // non thinned data
|
rt300@4
|
409 case SAVE_PRESET:
|
rt300@5
|
410 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@4
|
411 // Code
|
rt300@4
|
412 break;
|
rt300@4
|
413 case SAVE_DESET:
|
rt300@5
|
414 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@4
|
415 break;
|
rt300@28
|
416
|
rt300@5
|
417 case SCROLL_STOPPED:
|
rt300@5
|
418 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@22
|
419 cout << "SCROLL STOPPED EVENT\n";
|
rt300@22
|
420 break;
|
rt300@22
|
421 case SNAPPED_TO_PRESET:
|
rt300@22
|
422 theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID));
|
rt300@22
|
423 cout << "SCROLL STOPPED EVENT\n";
|
rt300@4
|
424 break;
|
rt300@25
|
425 case SWAP_VIEW:
|
rt300@25
|
426 theEvents.push_back(lEvent(evtType,0.0 , 0.0 , sliderID)); // slider ID is which view
|
rt300@25
|
427 break;
|
rt300@4
|
428 default:
|
rt300@25
|
429 // default is just an event type with no values
|
rt300@25
|
430 theEvents.push_back(lEvent(evtType));
|
rt300@4
|
431 break;
|
rt300@1
|
432 }
|
rt300@27
|
433 if(theEvents.size() > nextUploadQty && !logUploadInProgress){
|
rt300@27
|
434 //try to upload asynchronously
|
rt300@27
|
435 uploadEventLog(true);
|
rt300@7
|
436 }
|
rt300@9
|
437 //sessionTime = (ofGetSystemTime() - sessionStartTime);
|
rt300@28
|
438 totalInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime); // milliseconds
|
rt300@28
|
439
|
rt300@1
|
440 }
|
rt300@29
|
441 //--------------------------------------------------------------------
|
rt300@29
|
442 // called from newUser
|
rt300@29
|
443 void EventLogger::deleteLogs(){
|
rt300@29
|
444 // the
|
rt300@29
|
445 theEvents.clear();
|
rt300@29
|
446 string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME;
|
rt300@29
|
447 ofFile logFile(fname,ofFile::WriteOnly);
|
rt300@29
|
448 logFile << "";
|
rt300@29
|
449 logFile.close();
|
rt300@29
|
450 }
|
rt300@8
|
451 //---------------------------------------------------------------------------
|
rt300@7
|
452
|
rt300@7
|
453 void EventLogger::exitAndSave(){
|
rt300@25
|
454
|
rt300@25
|
455 if(!consentGiven){
|
rt300@25
|
456 logEvent(CONSENT_DENIED);
|
rt300@25
|
457 Json::Value jlogs = logsToJson();
|
rt300@25
|
458 // try to upload TODO (no - might hang and prevent exit???)
|
rt300@27
|
459 uploadEventLog(true);
|
rt300@25
|
460 return;
|
rt300@25
|
461 }
|
rt300@25
|
462 logEvent(APP_EXITED);
|
rt300@25
|
463 savedInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime);
|
rt300@7
|
464 // save user details
|
rt300@8
|
465 string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME;
|
rt300@8
|
466
|
rt300@25
|
467 // try to upload TODO (no - might hang and prevent exit???)
|
rt300@27
|
468 // do it async because event list needs to be cleared to prevent saving on device
|
rt300@27
|
469 uploadEventLog(false);
|
rt300@7
|
470
|
rt300@8
|
471 // write to file
|
rt300@25
|
472 // json without the logs that were uploaded!
|
rt300@25
|
473 Json::Value jlogs = logsToJson();
|
rt300@8
|
474 ofFile logFile(fname,ofFile::WriteOnly);
|
rt300@8
|
475 logFile << jlogs;
|
rt300@29
|
476 logFile.close();
|
rt300@8
|
477
|
rt300@8
|
478 }
|
rt300@8
|
479 //---------------------------------------------------------------------------
|
rt300@8
|
480
|
rt300@8
|
481 Json::Value EventLogger::logsToJson(){
|
rt300@8
|
482 // put all logged events into Json formatted string
|
rt300@8
|
483 Json::Value root;
|
rt300@8
|
484
|
rt300@8
|
485 vector<lEvent>::iterator eventIter;
|
rt300@8
|
486
|
rt300@22
|
487 root["programVersion"] = PROGRAM_VERSION;
|
rt300@8
|
488 root["userName"] = userName;
|
rt300@8
|
489 root["deviceID"] = deviceID;
|
rt300@25
|
490 root["uploadNumber"] = nextUploadNumber;
|
rt300@22
|
491 root["iOSdeviceType"] = iOSdeviceType;
|
rt300@25
|
492 root["savedInteractionTime"] = savedInteractionTime;
|
rt300@22
|
493 root["questionnaireCompleted"] = questionnaireCompleted;
|
rt300@22
|
494 root["questionnaireUploaded"] = questionnaireUploaded;
|
rt300@22
|
495 if(questionnaireCompleted && !questionnaireUploaded){
|
rt300@28
|
496 root["questionnaire"] = questionnaireToJson();
|
rt300@22
|
497 }
|
rt300@8
|
498
|
rt300@8
|
499 int i = 0;
|
rt300@8
|
500 for(eventIter = theEvents.begin(); eventIter < theEvents.end(); eventIter++){
|
rt300@8
|
501 root["events"][i] = (*eventIter).eventToJson();
|
rt300@8
|
502 i++;
|
rt300@7
|
503 }
|
rt300@25
|
504 root["numEventsHere"] = i;
|
rt300@8
|
505 return root;
|
rt300@8
|
506 }
|
rt300@22
|
507
|
rt300@8
|
508 //---------------------------------------------------------------------------
|
rt300@22
|
509
|
rt300@22
|
510 Json::Value EventLogger::questionnaireToJson(){
|
rt300@22
|
511 // put all answers into Json formatted string
|
rt300@22
|
512 Json::Value root;
|
rt300@22
|
513
|
rt300@22
|
514 vector<int>::iterator aIter;
|
rt300@22
|
515
|
rt300@22
|
516 Json::Value questionnaire;
|
rt300@22
|
517
|
rt300@22
|
518 int i = 0;
|
rt300@22
|
519 for(aIter = questionnaireAnswers.begin(); aIter < questionnaireAnswers.end(); aIter++){
|
rt300@22
|
520 questionnaire[i] = (*aIter);
|
rt300@22
|
521 i++;
|
rt300@22
|
522 }
|
rt300@28
|
523 cout << questionnaireComments << "\n";
|
rt300@22
|
524
|
rt300@22
|
525 root["qAnswers"] = questionnaire;
|
rt300@28
|
526 root["comments"] = questionnaireComments;
|
rt300@22
|
527 root["userName"] = userName;
|
rt300@22
|
528 root["deviceID"] = deviceID;
|
rt300@22
|
529 root["iOSdeviceType"] = iOSdeviceType;
|
rt300@22
|
530 root["programVersion"] = PROGRAM_VERSION;
|
rt300@22
|
531
|
rt300@22
|
532 return root;
|
rt300@22
|
533 }
|
rt300@8
|
534 //---------------------------------------------------------------------------
|
rt300@8
|
535 //---------------------------------------------------------------------------
|
rt300@22
|
536 //---------------------------------------------------------------------------
|