Skip to content

Commit f1115a8

Browse files
committed
Added display of use-stats to the "About" window.
Added display of total active use time, total number of new sessions, and number of files opened from file system. This required breaking out a few primate members of InterSpecUser and InterSpecApp. Also added note that these statics are kept locally and not telemetered anywhere.
1 parent 286aa6c commit f1115a8

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

InterSpec/InterSpecApp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class InterSpecApp : public Wt::WApplication
103103

104104
InterSpec *viewer();
105105

106+
boost::posix_time::time_duration activeTimeInCurrentSession() const;
107+
106108

107109
//userNameFromOS(): Caution, will return 'apache' if being served, from
108110
// an apache server, 'mobile' if on a iOS device, or blank upon failure.

InterSpec/InterSpecUser.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,29 @@ class InterSpecUser
205205

206206
const std::string &userName() const;
207207

208+
/** The number of new InterSpec sessions that has been created for this user. */
209+
int accessCount() const;
210+
211+
/** Approximate total amount of time user has actively used the app before the current session.
212+
213+
Counts time between user generated events in the app, but only if less than 5 minutes between interactions.
214+
See #InterSpecApp::notify for implementation of when time is added.
215+
216+
This value is only incremented #InterSpecApp::prepareForEndOfSession, so it does not include time from the current session.
217+
*/
218+
boost::posix_time::time_duration totalTimeInApp() const;
219+
220+
/** Approximate number of spectrum files opened.
221+
222+
The count is only incremented if #SpecMeasManager::checkIfPreviouslyOpened is called after opening a file, which is only
223+
called some of the time from #SpecMeasManager::displayFile, specifically I think only when files are opened from the
224+
filesystem.
225+
*/
226+
int numSpectraFilesOpened() const;
227+
228+
/** The UTC time when this user was first created in the database. */
229+
boost::posix_time::ptime firstAccessUTC() const;
230+
208231
//userFromViewer: a simple helper function to return the user from a
209232
// spectrum viewer pointer; necessary to break a "Member access into
210233
// incomplete type 'InterSpec'" issue.

src/InterSpecApp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,11 @@ InterSpec *InterSpecApp::viewer()
900900
}//InterSpec* viewer()
901901

902902

903+
boost::posix_time::time_duration InterSpecApp::activeTimeInCurrentSession() const
904+
{
905+
return m_activeTimeInSession;
906+
}
907+
903908
#if( BUILD_AS_ELECTRON_APP || BUILD_AS_OSX_APP || ANDROID || IOS )
904909
std::string InterSpecApp::externalToken()
905910
{

src/InterSpecUser.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,31 @@ const std::string &InterSpecUser::userName() const
13991399
return m_userName;
14001400
}
14011401

1402+
1403+
int InterSpecUser::accessCount() const
1404+
{
1405+
return m_accessCount;
1406+
}
1407+
1408+
1409+
boost::posix_time::time_duration InterSpecUser::totalTimeInApp() const
1410+
{
1411+
return m_totalTimeInApp;
1412+
}
1413+
1414+
1415+
int InterSpecUser::numSpectraFilesOpened() const
1416+
{
1417+
return m_spectraFilesOpened;
1418+
}
1419+
1420+
1421+
boost::posix_time::ptime InterSpecUser::firstAccessUTC() const
1422+
{
1423+
return m_firstAccessUTC;
1424+
}
1425+
1426+
14021427
Wt::Dbo::ptr<InterSpecUser> &InterSpecUser::userFromViewer( InterSpec *viewer )
14031428
{
14041429
static Dbo::ptr<InterSpecUser> dummy;

src/LicenseAndDisclaimersWindow.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <Wt/WAnimation>
3636
#include <Wt/WPushButton>
3737
#include <Wt/WGridLayout>
38+
#include <Wt/WEnvironment>
3839
#include <Wt/WApplication>
3940
#include <Wt/WStackedWidget>
4041
#include <Wt/WContainerWidget>
@@ -44,10 +45,12 @@
4445
#include <Wt/WServer>
4546
#endif
4647

48+
#include "SpecUtils/DateTime.h"
4749
#include "InterSpec/InterSpec.h"
4850
#include "InterSpec/AuxWindow.h"
4951
#include "SpecUtils/Filesystem.h"
5052
#include "InterSpec/InterSpecApp.h"
53+
#include "InterSpec/PhysicalUnits.h"
5154
#include "InterSpec/UseInfoWindow.h"
5255
#include "InterSpec/LicenseAndDisclaimersWindow.h"
5356

@@ -354,6 +357,40 @@ void LicenseAndDisclaimersWindow::dataStorageCreator( Wt::WContainerWidget *pare
354357
SpecUtils::ireplace_all( staticdir, "/", "\\" );
355358
#endif
356359

360+
361+
#if( USE_DB_TO_STORE_SPECTRA )
362+
bool displayStats = false;
363+
string totalUserTime, totalFilesOpened, totalSessions, firstAccess;
364+
365+
InterSpec *viewer = InterSpec::instance();
366+
Dbo::ptr<InterSpecUser> user = ((app && viewer) ? viewer->m_user : Dbo::ptr<InterSpecUser>());
367+
if( user )
368+
{
369+
try
370+
{
371+
totalSessions = std::to_string( user->accessCount() );
372+
totalFilesOpened = std::to_string( user->numSpectraFilesOpened() );
373+
boost::posix_time::time_duration totaltime = user->totalTimeInApp();
374+
// Note that if user has multiple sessions going, this next line wont be exactly correct, but close enough.
375+
totaltime += app->activeTimeInCurrentSession();
376+
totalUserTime = PhysicalUnits::printToBestTimeUnits( totaltime.total_seconds() );
377+
378+
const WDateTime utcStartTime = WDateTime::fromPosixTime( user->firstAccessUTC() );
379+
const int offset = app->environment().timeZoneOffset();
380+
firstAccess = utcStartTime.addSecs(60*offset).toString( "dd-MMM-yyyy" ).toUTF8();
381+
382+
// The alternative of using WLocalDateTime leaves the time in UTC...
383+
//const WLocalDateTime localStartTime = utcStartTime.toLocalTime();
384+
//firstAccess = localStartTime.toString("dd-MMM-yyyy").toUTF8();
385+
386+
displayStats = true;
387+
}catch(...)
388+
{
389+
// Dont expect this to ever really happen.
390+
}//try / catch
391+
}//if( app && viewer && viewer->m_user )
392+
#endif
393+
357394
auto server = WServer::instance();
358395
const int httpPort = server ? server->httpPort() : 0;
359396

@@ -380,6 +417,49 @@ void LicenseAndDisclaimersWindow::dataStorageCreator( Wt::WContainerWidget *pare
380417
"<div style=\"" + style + "\">http://127.0.0.1:" + std::to_string(httpPort) + "</div>"
381418
"</p>"
382419
;
420+
421+
#if( USE_DB_TO_STORE_SPECTRA )
422+
if( displayStats )
423+
{
424+
contents += "<div style=\"margin-top: 10px\"><p>"
425+
"You have actively used InterSpec for approximately "
426+
+ totalUserTime + ", to open " + totalFilesOpened
427+
+ " files, over " + totalSessions + " sessions since " + firstAccess + "."
428+
"</p></div>";
429+
}//if( displayStats )
430+
#endif //if( USE_DB_TO_STORE_SPECTRA )
431+
432+
433+
#if( BUILD_FOR_WEB_DEPLOYMENT )
434+
// Statement here would depend on web-server policies
435+
#else
436+
contents +=
437+
"<div style=\"margin-top: 10px\"><p>"
438+
"InterSpec does not send or receive data external to your device"
439+
#if( USE_GOOGLE_MAP )
440+
", except when the Google Maps feature is used"
441+
#endif
442+
"."
443+
444+
#if( USE_DB_TO_STORE_SPECTRA )
445+
"<br />InterSpec does locally"
446+
" store preferences, spectra you load, saved app states, and use"
447+
" statistics."
448+
" This information does not leave your device, and can be deleted by removing the user data"
449+
" directory shown above."
450+
#endif
451+
452+
#if( USE_GOOGLE_MAP )
453+
"<br />When the Google Maps feature is used, the spectrum file location information is sent to"
454+
" Google in order to receive maps of the relevant location."
455+
#endif
456+
"</p></div>";
457+
458+
#endif //#if( BUILD_FOR_WEB_DEPLOYMENT ) / else
459+
460+
461+
462+
383463
}else
384464
{
385465
contents = "Error retrieving directory data";

0 commit comments

Comments
 (0)