diff --git a/Page-tracking-extension/content.js b/Page-tracking-extension/content.js
index 52f613e..e1ba5a4 100644
--- a/Page-tracking-extension/content.js
+++ b/Page-tracking-extension/content.js
@@ -7,38 +7,37 @@ $(document).ready(function() {
var end;
var time_spent;
- window.addEventListener('focus', function() {
- start = Date.now();
- });
-
+ // $(window).on('focus', function() {
+ start = Date.now();
+ // });
console.log("start = ", start)
-
- $(window).on('blur', function() {
- end = new Date().getTime();
- });
-
- console.log("end = ", end);
- time_spent = end - start;
- console.log(time_spent/1000)
+ $(window).on('blur', function() {
+ end = Date.now();
+ console.log("end = ", end);
+ time_spent = (end - start)/1000;
+ console.log("time_spent = ", time_spent);
+
+ var evtData = {
+ "userId": user_id,
+ "evt_type": "Time Spent",
+ "pageHTML": document.URL,
+ "object_id": 0,
+ "evt_datetime": time_spent,
+ "evt_timestamp": Date.now()
+ };
+ console.log(evtData);
- var evtData = {
- "userId": user_id,
- "evt_type": "Time Spent",
- "pageHTML": document.URL,
- "object_id": 0,
- "evt_datetime": (time_spent/1000).toString()
- };
-
- // console.log(evtData);
- // Sending data to background.js
- chrome.runtime.sendMessage({'evtData': evtData, 'quesData': null}, function(response) {
- // console.log(response.BgResponse);
+ // Sending data to background.js
+ chrome.runtime.sendMessage({'evtData': evtData, 'quesData': null}, function(response) {
+ // console.log(response.BgResponse);
+ });
});
});
+
// Question click event handler
$(document).ready(function(evt) {
var ques_id = document.URL.split('/')[4];
@@ -53,7 +52,8 @@ $(document).ready(function(evt) {
"evt_type": "Visited",
"pageHTML": document.URL,
"object_id": ques_id,
- "evt_datetime": date + ' ' + time
+ "evt_datetime": date + ' ' + time,
+ "evt_timestamp": Date.now()
};
var tagListChildren = document.getElementsByClassName("post-taglist")[0].children;
@@ -79,7 +79,6 @@ $(document).ready(function(evt) {
"Tags": tags
};
- // Sending data to background.js
chrome.runtime.sendMessage({'evtData': evtData, 'quesData': quesData}, function(response) {
// console.log(response.BgResponse);
});
@@ -101,7 +100,8 @@ $('#submit-button').on('click', function() {
"evt_type": "Posted Answer to",
"pageHTML": document.URL,
"object_id": ques_id,
- "evt_datetime": date + ' ' + time
+ "evt_datetime": date + ' ' + time,
+ "evt_timestamp": Date.now()
};
var tagListChildren = document.getElementsByClassName("post-taglist")[0].children;
@@ -121,35 +121,32 @@ $('#submit-button').on('click', function() {
"object_id": ques_id,
"pageHTML": document.URL,
"votes": $(".vote-count-post")[0].innerHTML,
- "answers": answers,
- "views": parseInt($(".label-key")[3].childNodes[1].innerHTML.split(' ')[0].split(',').join('')),
+ "answers": answers, "views": parseInt($(".label-key")[3].childNodes[1].innerHTML.split(' ')[0].split(',').join('')),
"DateTime": $(".label-key")[1].getAttribute("title"),
"Tags": tags
};
+
+ chrome.runtime.sendMessage({'evtData': evtData, 'quesData': quesData}, function(response) {
+ // console.log(response.BgResponse);
+ });
- // var ansData = {
- // "question_id": ques_id,
- // "pageHTML": document.URL,
- // "content": $('#wmd-preview').eq(0).text(),
- // "DateTime": Date.now()
- // };
-
- // Check for errors and send the data
- if($('.wmd-input processed validation-error').length == 0 && $('.message-text').length == 0) {
- // Sending data to background.js
- console.log("Sending the data");
- chrome.runtime.sendMessage({'evtData': evtData, 'quesData': quesData}, function(response) {
- // console.log(response.BgResponse);
- });
- }
- else {
- console.log("Did not send the data");
- }
+ // Tried to actually send data only after the constraints are removed. But facing problem to check the updated HTML after
+ // the answer validation is done
+ // if($('.wmd-input processed validation-error').length == 0 && $('.message-text').length == 0) {
+ // Sending data to background.js
+ // console.log("Sending the data");
+ // chrome.runtime.sendMessage({'evtData': evtData, 'quesData': quesData}, function(response) {
+ // // console.log(response.BgResponse);
+ // });
+ // }
+ // else {
+ // console.log("Did not send the data");
+ // }
});
// Share the question tracking
-$('.short-link').eq(0).on('click', function() {
+$('.short-link').on('click', function() {
// console.log("share question");
var ques_id = document.URL.split('/')[4];
@@ -161,10 +158,11 @@ $('.short-link').eq(0).on('click', function() {
var evtData = {
"userId": user_id,
- "evt_type": "Shared Question",
+ "evt_type": "Shared",
"pageHTML": document.URL,
- "object_id": ques_id,
- "evt_datetime": date + ' ' + time
+ "object_id": this.getAttribute('href').split('/')[2],
+ "evt_datetime": date + ' ' + time,
+ "evt_timestamp": Date.now()
};
// Question details
@@ -181,7 +179,7 @@ $('.short-link').eq(0).on('click', function() {
answers = $(".subheader.answers-subheader")[0].childNodes[1].childNodes[1].innerHTML;
var quesData = {
- "object_type": "Question",
+ "object_type": "Q/A",
"object_id": ques_id,
"pageHTML": document.URL,
"votes": $(".vote-count-post")[0].innerHTML,
@@ -211,11 +209,10 @@ $(".vote-up-off").on('click', function() {
"evt_type": "UpVoted",
"pageHTML": document.URL,
"object_id": this.previousElementSibling.getAttribute('value'),
- "evt_datetime": date + ' ' + time
+ "evt_datetime": date + ' ' + time,
+ "evt_timestamp": Date.now()
};
- console.log(evtData);
- // Sending data to background.js
chrome.runtime.sendMessage({'evtData': evtData, 'quesData': null}, function(response) {
// console.log(response.BgResponse);
});
@@ -236,85 +233,34 @@ $(".vote-down-off").on('click', function() {
"evt_type": "DownVoted",
"pageHTML": document.URL,
"object_id": this.previousElementSibling.previousElementSibling.previousElementSibling.getAttribute('value'),
- "evt_datetime": date + ' ' + time
+ "evt_datetime": date + ' ' + time,
+ "evt_timestamp": Date.now()
};
- console.log(evtData);
- // Sending data to background.js
chrome.runtime.sendMessage({'evtData': evtData, 'quesData': null}, function(response) {
// console.log(response.BgResponse);
});
});
-
-// // Adding a comment
-// var $addCommentLinks = $('.js-add-link.comments-link.disabled-link')
-
-// for(var i=0; i < $addCommentLinks.length; i++) {
-
-// // console.log($('#answer-218390').eq(i).find('span.relativetime').eq(0).attr('title'));
-
-// $addCommentLinks.eq(i).on('click', function() {
-
-// console.log($addCommentLinks.eq(i));
-
-// // var DOMAnswer_id = "#answer-" + ans_id;
-// // console.log($(DOMAnswer_id).eq(i).find('span.vote-count-post').eq(0));
-
-// // var ques_id = document.URL.split('/')[4];
-// // var user_id = "dummy";
-
-// // var evtData = {
-// // "userId": user_id,
-// // "evt_type": "Add Comment",
-// // "pageHTML": document.URL,
-// // "question_id": ques_id,
-// // "evt_datetime": Date.now()
-// // };
-
-// // var tags = null
-
-// // var quesData = {
-// // "object_type": "Answer",
-// // "object_id": ans_id,
-// // "pageHTML": document.URL,
-// // "votes": $(DOMAnswer_id).eq(i).find('span.vote-count-post').eq(0).text,
-// // "answers": 0,
-// // "views": null,
-// // "DateTime": $(DOMAnswer_id).eq(i).find('span.relativetime').eq(0).attr('title'),
-// // "Tags": tags
-// // };
-
-// // console.log(quesData);
-// });
-// }
-
-// var addCommentEventHandler = function(ans_id) {
+console.log($('.btn'));
+$('.btn').on('click', function() {
+ var ques_id = document.URL.split('/')[4];
+ var user_id = "dummy";
-// var ques_id = document.URL.split('/')[4];
-// var user_id = "dummy";
-// var DOMAnswer_id = "#answer-" + ans_id;
-
-// var evtData = {
-// "userId": user_id,
-// "evt_type": "Add Comment",
-// "pageHTML": document.URL,
-// "question_id": ques_id,
-// "evt_datetime": Date.now()
-// };
-
-// var tags = null
-
-// var quesData = {
-// "object_type": "Answer",
-// "object_id": ans_id,
-// "pageHTML": document.URL,
-// "votes": $(DOMAnswer_id).eq(0).find('span.vote-count-post')[0].innerHTML,
-// "answers": 0,
-// "views": null,
-// "DateTime": $(DOMAnswer_id).eq(0).find('span.relativetime').eq(0).attr('title'),
-// "Tags": tags
-// };
-
-// console.log(quesData);
-// }
+ var today = new Date();
+ var date = (today.getMonth() + 1) + '-' + (today.getDate()) + '-' + today.getFullYear();
+ var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
+
+ var evtData = {
+ "userId": user_id,
+ "evt_type": "Asked Question",
+ "pageHTML": document.URL,
+ "object_id": 0,
+ "evt_datetime": date + ' ' + time,
+ "evt_timestamp": Date.now()
+ };
+ console.log(evtData);
+ chrome.runtime.sendMessage({'evtData': evtData, 'quesData': null}, function(response) {
+ // console.log(response.BgResponse);
+ });
+});
diff --git a/Page-tracking-extension/popup.html b/Page-tracking-extension/popup.html
index 82c6048..9e79d5a 100644
--- a/Page-tracking-extension/popup.html
+++ b/Page-tracking-extension/popup.html
@@ -1,12 +1,12 @@
- GTmetrix Analyzer
+ Behavioral Logging
- GTmetrix Analyzer
+ Behavioral Logging
\ No newline at end of file
diff --git a/UserTracking.db b/UserTracking.db
index 6c593b2..4cd4fcb 100644
Binary files a/UserTracking.db and b/UserTracking.db differ
diff --git a/app.py b/app.py
index 21c80a5..580a6a9 100644
--- a/app.py
+++ b/app.py
@@ -1,14 +1,14 @@
from flask import Flask, request, render_template, redirect,\
-url_for, session, flash, jsonify
+ url_for, session, flash, jsonify
from flask_sqlalchemy import SQLAlchemy
from functools import wraps
from flask_cors import CORS
import simplejson as json
import sqlite3 as sql
-import datetime as dt
+import datetime
import time
import os
-
+import flask_login
app = Flask(__name__)
CORS(app)
@@ -18,8 +18,8 @@
# Create the sqlalchemy object
db = SQLAlchemy(app)
-# Should be imported after "db" creation as models.py uses db
-from models import *
+# Global variable
+entered_UserId = ""
# Login required decorator
def login_required(f):
@@ -37,18 +37,17 @@ def wrap(*args, **kwargs):
@login_required
def home():
userDetails = []
+ username = request.args.get('userId')
with sql.connect("UserTracking.db") as connection:
- print "inside db connection"
+
c = connection.cursor()
- c.execute('SELECT evt_type, pageHTML, evt_datetime FROM UserActions where userId = "dummy" and evt_datetime != "NaN" ')
+ c.execute('SELECT evt_type, pageHTML, evt_datetime FROM UserActions where userId = ? ORDER BY tmStamp DESC', [username])
userDetails = c.fetchall()
posts = []
for info in userDetails:
-
post = info[0] + " --> " + info[1] + " --> " + info[2]
- # print post
posts.append(post)
return render_template("index.html", posts=posts)
@@ -58,48 +57,71 @@ def home():
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
+ with sql.connect("UserTracking.db") as connection:
+ c = connection.cursor()
+
+ if request.method == 'GET':
+ # print "INSIDE GET REQUEST"
+ c.execute('SELECT userId, loginDataTime FROM UserHistory ORDER BY tmStamp DESC')
+ loginHistory = c.fetchall()
+ print "loginHistory = ", loginHistory
+
+ logins = []
+ for loginHis in loginHistory:
+ login = loginHis[0] + " --> " + loginHis[1]
+ logins.append(login)
+
+ print logins
+ return render_template("login.html", error=error, logins=logins)
- if request.method == 'POST':
- if request.form['username'] != "admin" or request.form['password'] != "admin":
- error = "Invalid credentials. Please try again"
- else:
- loginStartTime = time.time()
- print "curr time = ", str(loginStartTime)
-
- session['logged_in'] = True
- with sql.connect("UserTracking.db") as connection:
- c = connection.cursor()
- c.execute('SELECT * FROM UserActions where userId = "admin"')
- loginInfo = c.fetchall()
+ with sql.connect("UserTracking.db") as connection:
+ c = connection.cursor()
+
+ username = request.form['username']
+ password = request.form['password']
+
+ if request.method == 'POST':
+ validCount = c.execute('SELECT count(password) FROM UserDetails WHERE userId = ? and password = ?', [username, password]).fetchall()[0][0]
+ print "validCount = ", validCount
+
+ if validCount == 0:
+ error = "Invalid credentials. Please try again"
+ else:
+ session['logged_in'] = True
+ # Maintain global variable to store current username
+ global entered_UserId
+ entered_UserId = username
- print "from login", request.form['username']
- return redirect(url_for('home', userId=request.form['username']))
+ # Get login time
+ now = datetime.datetime.now()
+ curr_time = now.strftime("%Y-%m-%d %I:%M:%S %p")
+ curr_timestamp = int(time.time())
+ print curr_timestamp
- return render_template("login.html", error=error)
+ c.execute('INSERT INTO UserHistory VALUES (?,?,?)', [username, curr_time, curr_timestamp])
+ return redirect(url_for('home', userId=request.form['username']))
+
+ return render_template("login.html", error=error)
@app.route('/adduser', methods=['GET', 'POST'])
def adduser():
- info = None
-
- # Post request
- if request.method == 'POST':
+ info = ""
- if request.form['username'] == "" or request.form['password'] == "":
+ if request.method == 'POST':
+
+ if not request.form['username'] or not request.form['password']:
info = "Login credentials cannot be empty"
else:
- loginStartTime = dt.datetime.now()
- print str(loginStartTime)
-
- # session['logged_in'] = True
with sql.connect("UserTracking.db") as connection:
c = connection.cursor()
- c.execute('INSERT INTO UserDetails VALUES(?,?)', [request.form['username'], request.form['password']])
- loginInfo = c.fetchall()
-
- info = "User created"
- print info
- print loginInfo
+ userExists = c.execute('SELECT count(password) FROM UserDetails WHERE userId = ?', [request.form['username']]).fetchall()[0][0]
+ if userExists != 0:
+ info = "UserId already exists"
+ else:
+ c.execute('INSERT INTO UserDetails VALUES(?,?)', [request.form['username'], request.form['password']])
+ loginInfo = c.fetchall()
+ info = "User created"
return render_template("adduser.html", info=info)
# Get request
@@ -109,16 +131,16 @@ def adduser():
@app.route('/TrackingData', methods=["POST"])
def TrackingData():
+
req_json = request.get_json()
evtData = req_json['evtData']
quesData = req_json['quesData']
- # print evtData
with sql.connect("UserTracking.db") as connection:
c = connection.cursor()
- c.execute('INSERT INTO UserActions VALUES(?,?,?,?,?)', \
- [evtData['userId'], evtData['evt_type'], evtData['pageHTML'], \
- evtData['object_id'], evtData['evt_datetime']])
+ c.execute('INSERT INTO UserActions VALUES(?,?,?,?,?,?)', \
+ [entered_UserId, evtData['evt_type'], evtData['pageHTML'], \
+ evtData['object_id'], evtData['evt_datetime'], evtData['evt_timestamp']])
# Future work - If object_id already exists, dont insert the column again
if quesData != None:
c.execute('INSERT INTO ObjectDetails VALUES(?,?,?,?,?,?,?,?)', \
@@ -128,9 +150,6 @@ def TrackingData():
return ""
-
-
-
@app.route('/logout')
@login_required
def logout():
diff --git a/db_create.py b/db_create.py
deleted file mode 100644
index 5ea79e7..0000000
--- a/db_create.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Import db that is created in app.py
-from app import db
-# Import schema
-from models import UserActions
-
-
-# Create the database and db tables
-db.create_all() # Initializes the database based on the
- # schema defined in models.py file
-
-# # Insert
-# # db.session.deleteall(BlogPost)
-# db.session.add(BlogPost("Good", "I\'m good."))
-# db.session.add(BlogPost("Well", "I\'m well."))
-
-# # Commit the changes
-# db.session.commit()
\ No newline at end of file
diff --git a/models.py b/models.py
deleted file mode 100644
index 8daacbb..0000000
--- a/models.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from app import db
-
-class UserDetails(db.Model):
- __tablename__ = "UserDetails"
-
- # Three variables goes to three columns in the database
- user_id = db.Column(db.Integer, primary_key=True)
- user_name = db.Column(db.String, nullable=False)
- password = db.Column(db.String, nullable=False)
-
- def __init__(self, user_name, password):
- self.user_name = user_name
- self.password = password
-
- def __repr__(self):
- return '{}-{}-{}'.format(self.user_id, self.user_name, self.password)
-
-
-class UserHistory(db.Model):
- __tablename__ = "UserHistory"
-
- # Three variables goes to three columns in the database
- user_id = db.Column(db.Integer, primary_key=True)
- login_date = db.Column(db.String, nullable=False)
- login_time = db.Column(db.String, nullable=False)
-
- def __init__(self, login_date, login_time):
- self.login_date = login_date
- self.login_time = login_time
-
- def __repr__(self):
- return '{}-{}-{}'.format(self.user_id, self.login_date, self.login_time)
-
-
-class UserActions(db.Model):
- __tablename__ = "UserActions"
-
- # Three variables goes to three columns in the database
- ques_id = db.Column(db.Integer, primary_key=True)
- votes = db.Column(db.Integer, nullable=False)
- answers = db.Column(db.Integer, nullable=False)
- views = db.Column(db.Integer, nullable=False)
-
- def __init__(self, ques_id, votes, answers, views):
- self.ques_id = ques_id
- self.votes = votes
- self.answers = answers
- self.views = views
-
- def __repr__(self):
- return '{}-{}-{}-{}'.format(self.ques_id, self.votes, self.answers, self.views)
-
diff --git a/sql.py b/sql.py
index 8d0d1eb..afea4a5 100644
--- a/sql.py
+++ b/sql.py
@@ -3,16 +3,12 @@
with sql.connect("UserTracking.db") as connection:
c = connection.cursor()
# c.execute("DROP TABLE UserActions")
- c.execute("CREATE TABLE UserActions(userId TEXT, evt_type TEXT, pageHTML TEXT, object_id INT, evt_datetime TEXT)")
+ c.execute("CREATE TABLE UserActions(userId TEXT, evt_type TEXT, pageHTML TEXT, object_id INT, evt_datetime TEXT, tmStamp INT)")
# c.execute("DROP TABLE ObjectDetails")
c.execute("CREATE TABLE ObjectDetails(object_type TEXT, object_id INT, pageHTML TEXT, votes INT, answers INT, views INT, create_datetime TEXT, tags TEXT)")
# c.execute("DROP TABLE UserHistory")
- c.execute("CREATE TABLE UserHistory(userId TEXT, loginDataTime TEXT, logoutDateTime)")
+ c.execute("CREATE TABLE UserHistory(userId TEXT, loginDataTime TEXT, tmStamp INT)")
# c.execute("DROP TABLE UserDetails")
c.execute("CREATE TABLE UserDetails(userId TEXT, password TEXT)")
- # c.execute("INSERT INTO UserDetails VALUES ('sss', 'qqq')")
- # c.execute("INSERT INTO UserDetails VALUES ('aaa', 'bbb')")
- # c.execute("INSERT INTO UserDetails VALUES ('ccc', 'ddd')")
-
\ No newline at end of file
diff --git a/static/style.css b/static/style.css
index dab82d7..cee153c 100644
--- a/static/style.css
+++ b/static/style.css
@@ -13,7 +13,7 @@ padding: 50px;
.login {
margin: 20px auto;
-width: 300px;
+width: 350px;
}
.login-screen {
@@ -21,13 +21,14 @@ background-color: #FFF;
padding: 20px;
border-radius: 5px
}
-
+
.app-title {
text-align: left;
color: #777;
}
.add-user-title {
+left-margin: 20px;
text-align: right;
color: #777;
}
@@ -35,6 +36,7 @@ color: #777;
.login-form {
text-align: center;
}
+
.control-group {
margin-bottom: 10px;
}
@@ -43,6 +45,12 @@ margin-bottom: 10px;
left-margin: 20px;
}
+.login-form-scroll {
+ height:350px;
+ overflow-y: scroll;
+ margin: 60px 0;
+}
+
table {
border-collapse: separate;
border-spacing: 10px 0;
diff --git a/templates/adduser.html b/templates/adduser.html
index 0f1d9d5..b62ebef 100644
--- a/templates/adduser.html
+++ b/templates/adduser.html
@@ -43,15 +43,17 @@
+
+
+ {% if info %}
+
{{ info }}
+ {% endif %}
-
- {% if error %}
- Info: {{ info }}
- {% endif %}
+