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