5

I have seen answers to see how long a user spends on a page using Javascript, but my knowledge of JS is lacking (much less integrating JS into my Python/Flask framework).

My objective is to create a web application that users can enter data into, while the time spent (both duration and what time during the day) doing the task is recorded.

I am using Python, Flask, WTForms, and SQLAlchemy for most of the functionality. From my views.py file, I have this configured:

@app.route('/logpage', methods=['GET', 'POST'])
@login_required
def logpage():
    form = LogForm()

    if form.validate_on_submit():
        entry = LogData(sessionid=form.sessionid.data, user_id=current_user.get_id(), endtime=datetime.utcnow())
        db.session.add(entry)
        db.session.commit()

        return redirect(url_for('home'))

    return render_template('logpage.html', form=form)

When the user hits submit, the Session ID, the user's ID, and the endtime is recorded to a PostgreSQL server. I tried setting pageload = datetime.utcnow() before the form validation in hopes it would store the time the page loaded, but it seems to save the same time as end time.

I was trying to figure out a way to write the current date time to the SQL entry/row and entering to the same row when the form validates, but I am unaware of how to write to the same row twice. Perhaps something with the primary key and linking them? I will continue to investigate this.

I would like a way to save the datetime this page loads so it can be compared to the time the form is submitted. Is there a straightforward way to accomplish this without javascript?

  • you could use jquery to have a counter start counting and then send the result with form. – senaps Sep 20 '17 at 10:39
  • @senaps : I will try that, but I really also wanted the time stamp of starting and stopping to see when the jobs are being done. I guess I can record the end time and subtract the recorded time? Inelegant but it might work. Thanks for the reply. – reflects_ark Sep 20 '17 at 13:04
  • I am considering using the TimeMe.JS (https://github.com/jasonzissman/TimeMe.js) library to time how long the user is on the page, but I need to configure it to continue to run even when a user minimizes/goes to another tab or find a similar library that does this. – reflects_ark Sep 20 '17 at 14:24

1 Answers1

1

You can use a Flask session to track the start time. It's implemented on top of browser cookies.

http://flask.pocoo.org/docs/0.12/quickstart/#sessions

You need to implement a secret key for the app (as shown in the quickstart example), and then you can use the session object as a key value store for user-specific information.

For your particular use case, it might be something like:

@app.route('/logpage', methods=['GET', 'POST'])
@login_required
def logpage():
    form = LogForm()

    if form.validate_on_submit():
        entry = LogData(sessionid=form.sessionid.data, user_id=current_user.get_id(), 
                        starttime=session.pop('start_time', None), endtime=datetime.utcnow())
        db.session.add(entry)
        db.session.commit()

        return redirect(url_for('home'))

    session['start_time'] = datetime.utcnow()

    return render_template('logpage.html', form=form)

pageload = datetime.utcnow() before the form validation didn't work because:

  • this variable would be local to the scope of the function and wouldn't persist after the function completes
  • even if the variable weren't local to the scope of the function call, the same function is being called for both GET and POST, so it would be overridden when the user posts the form

One more thing to be aware of is that you can't trust the user to be using cookies or to allow JavaScript, so you should consider how your program would handle null start times in the database.

Rach Sharp
  • 2,324
  • 14
  • 31
  • This is exactly what I needed! The start time and end times are being recorded flawlessly. Glad I don't have to mess with JS for this. I appreciate your help, thanks for the response. – reflects_ark Sep 23 '17 at 17:04