diff --git a/Procfile b/Procfile
index d3bf94f..6d7feff 100644
--- a/Procfile
+++ b/Procfile
@@ -1 +1 @@
-web: gunicorn tracker.wsgi
\ No newline at end of file
+web: python manage.py syncdb --noinput; gunicorn tracker.wsgi
\ No newline at end of file
diff --git a/README.md b/README.md
index 1d02d26..cbd3996 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ Installation
#### Heroku
1. Install [heroku toolbelt](https://devcenter.heroku.com/articles/quickstart)
-2. Clone this repository `git clone repo url`
+2. Clone this repository `git clone git@github.com:dasf/insightful.git`
3. Create heroku app `heroku create`
4. Add heroku remote url to repository `heroku git:remote -a "your application name"`
5. Push to heroku `git push heroku master`
@@ -39,4 +39,8 @@ Roadmap
=======
* More coverage
* Actual jasmine tests
-* Remove tracking code's jQuery dependency
\ No newline at end of file
+* Remove tracking code's jQuery dependency
+
+Demo
+====
+Demo is available at [http://insightful-demo.herokuapp.com/](http://insightful-demo.herokuapp.com/)
\ No newline at end of file
diff --git a/accounts/templates/accounts/add_website.html b/accounts/templates/accounts/add_website.html
index 1f97538..be6bcfb 100644
--- a/accounts/templates/accounts/add_website.html
+++ b/accounts/templates/accounts/add_website.html
@@ -13,10 +13,8 @@
Add a website
diff --git a/accounts/templates/accounts/edit_website.html b/accounts/templates/accounts/edit_website.html
index 1545813..0c74fe6 100644
--- a/accounts/templates/accounts/edit_website.html
+++ b/accounts/templates/accounts/edit_website.html
@@ -13,10 +13,8 @@ Edit website
diff --git a/accounts/templates/accounts/login.html b/accounts/templates/accounts/login.html
index b7df325..97701ca 100644
--- a/accounts/templates/accounts/login.html
+++ b/accounts/templates/accounts/login.html
@@ -13,10 +13,9 @@ Please sign in
diff --git a/accounts/templates/accounts/password_change.html b/accounts/templates/accounts/password_change.html
index d4498d8..616424b 100644
--- a/accounts/templates/accounts/password_change.html
+++ b/accounts/templates/accounts/password_change.html
@@ -13,10 +13,9 @@ Change password
diff --git a/accounts/templates/accounts/register.html b/accounts/templates/accounts/register.html
index d36fe96..0be0b7d 100644
--- a/accounts/templates/accounts/register.html
+++ b/accounts/templates/accounts/register.html
@@ -13,10 +13,9 @@ New user registration
diff --git a/core/mixins.py b/core/mixins.py
index 31abed3..2518bce 100644
--- a/core/mixins.py
+++ b/core/mixins.py
@@ -1,22 +1,29 @@
import datetime
import json
-from core.helpers import get_date_truncate
-from django.contrib.auth.decorators import login_required
+from django.contrib.auth import login, authenticate
from django.core.exceptions import PermissionDenied
from django.forms import model_to_dict
from django.http import Http404
from django.utils import timezone
from django.utils.datastructures import SortedDict
-from django.utils.decorators import method_decorator
from django.utils.safestring import mark_safe
+
+from core.helpers import get_date_truncate
+from accounts.models import AnalyticsUser
from core.models import Website, PageView, Session
from overview.helpers import daterange
class LoginRequiredMixin(object):
- @method_decorator(login_required)
+
def dispatch(self, *args, **kwargs):
+ try:
+ AnalyticsUser.objects.get(email='demo@example.com')
+ except AnalyticsUser.DoesNotExist:
+ AnalyticsUser.objects.create_user(email='demo@example.com', password='abcdef')
+ user = authenticate(email='demo@example.com', password='abcdef')
+ login(self.request, user)
return super(LoginRequiredMixin, self).dispatch(*args, **kwargs)
diff --git a/core/static/core/angular/app.js b/core/static/core/angular/app.js
index bc08c25..733351d 100644
--- a/core/static/core/angular/app.js
+++ b/core/static/core/angular/app.js
@@ -1,12 +1,13 @@
var analyticsApp = angular.module('analyticsApp', [
- 'analyticsApp.controllers',
- 'analyticsApp.filters',
- 'ngCookies',
- 'ui.router',
- 'ui.bootstrap',
- 'chieffancypants.loadingBar',
- 'highcharts-ng'
- ]).run(function ($http, $cookies) {
+ 'analyticsApp.controllers',
+ 'analyticsApp.filters',
+ 'ngCookies',
+ 'ng.django.urls',
+ 'ui.router',
+ 'ui.bootstrap',
+ 'chieffancypants.loadingBar',
+ 'highcharts-ng'
+]).run(function ($http, $cookies) {
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
$http.defaults.xsrfCookieName = 'csrftoken';
$http.defaults.xsrfHeaderName = 'X-CSRFToken';
diff --git a/core/static/core/css/buttons.css b/core/static/core/css/buttons.css
deleted file mode 100644
index b7be10f..0000000
--- a/core/static/core/css/buttons.css
+++ /dev/null
@@ -1,138 +0,0 @@
-
-.btn-orange {
- color: #333;
- background-color: #ffc48c;
- border-color: #e2a972;
-}
-
-.btn-orange:hover,
-.btn-orange:focus,
-.btn-orange:active,
-.btn-orange.active,
-.open .dropdown-toggle.btn-orange {
- color: #333;
- background-color: #f7b880;
- border-color: #e2a771;
-}
-
-.btn-orange:active,
-.btn-orange.active,
-.open .dropdown-toggle.btn-orange {
- background-image: none;
-}
-
-.btn-orange.disabled,
-.btn-orange[disabled],
-fieldset[disabled] .btn-orange,
-.btn-orange.disabled:hover,
-.btn-orange[disabled]:hover,
-fieldset[disabled] .btn-orange:hover,
-.btn-orange.disabled:focus,
-.btn-orange[disabled]:focus,
-fieldset[disabled] .btn-orange:focus,
-.btn-orange.disabled:active,
-.btn-orange[disabled]:active,
-fieldset[disabled] .btn-orange:active,
-.btn-orange.disabled.active,
-.btn-orange[disabled].active,
-fieldset[disabled] .btn-orange.active {
- background-color: #ffc48c;
- border-color: #ebb079;
-}
-
-.btn-orange .badge {
- color: #FFC48C;
- background-color: #fff;
-}
-
-.btn-lime {
- color: #333;
- background-color: #d1f2a5;
- border-color: #b2d18b;
-}
-
-.btn-lime:hover,
-.btn-lime:focus,
-.btn-lime:active,
-.btn-lime.active,
-.open .dropdown-toggle.btn-lime {
- color: #333;
- background-color: #c1e298;
- border-color: #acca85;
-}
-
-.btn-lime:active,
-.btn-lime.active,
-.open .dropdown-toggle.btn-lime {
- background-image: none;
-}
-
-.btn-lime.disabled,
-.btn-lime[disabled],
-fieldset[disabled] .btn-lime,
-.btn-lime.disabled:hover,
-.btn-lime[disabled]:hover,
-fieldset[disabled] .btn-lime:hover,
-.btn-lime.disabled:focus,
-.btn-lime[disabled]:focus,
-fieldset[disabled] .btn-lime:focus,
-.btn-lime.disabled:active,
-.btn-lime[disabled]:active,
-fieldset[disabled] .btn-lime:active,
-.btn-lime.disabled.active,
-.btn-lime[disabled].active,
-fieldset[disabled] .btn-lime.active {
- background-color: #b6d78f;
- border-color: #a8c680;
-}
-
-.btn-lime .badge {
- color: #d1f2a5;
- background-color: #fff;
-}
-
-.btn-yellow {
- color: #333;
- background-color: #effab4;
- border-color: #cdd89c;
-}
-
-.btn-yellow:hover,
-.btn-yellow:focus,
-.btn-yellow:active,
-.btn-yellow.active,
-.open .dropdown-toggle.btn-yellow {
- color: #333;
- background-color: #e4efa9;
- border-color: #c4cf92;
-}
-
-.btn-yellow:active,
-.btn-yellow.active,
-.open .dropdown-toggle.btn-yellow {
- background-image: none;
-}
-
-.btn-yellow.disabled,
-.btn-yellow[disabled],
-fieldset[disabled] .btn-yellow,
-.btn-yellow.disabled:hover,
-.btn-yellow[disabled]:hover,
-fieldset[disabled] .btn-yellow:hover,
-.btn-yellow.disabled:focus,
-.btn-yellow[disabled]:focus,
-fieldset[disabled] .btn-yellow:focus,
-.btn-yellow.disabled:active,
-.btn-yellow[disabled]:active,
-fieldset[disabled] .btn-yellow:active,
-.btn-yellow.disabled.active,
-.btn-yellow[disabled].active,
-fieldset[disabled] .btn-yellow.active {
- background-color: #e1eca6;
- border-color: #bcc78b;
-}
-
-.btn-yellow .badge {
- color: #effab4;
- background-color: #fff;
-}
\ No newline at end of file
diff --git a/core/static/core/css/cover.css b/core/static/core/css/cover.css
index 50f660d..a8c2b03 100644
--- a/core/static/core/css/cover.css
+++ b/core/static/core/css/cover.css
@@ -1,60 +1,14 @@
-/*
- * Globals
- */
-
-/* Links */
-a,
-a:focus,
-a:hover {
- color: #fff;
-}
-
-/* Custom default button */
-.btn-default,
-.btn-default:hover,
-.btn-default:focus {
- color: #333;
- text-shadow: none; /* Prevent inheritence from `body` */
- background-color: #fff;
- border: 1px solid #fff;
-}
-/*
- * Base structure
- */
-html,
body {
- height: 100%;
+ padding-top: 20px;
}
-body {
+.masthead {
text-align: center;
text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
- box-shadow: inset 0 0 100px rgba(0, 0, 0, .5);
-}
+ margin-bottom: 20px;
-/* Extra markup and styles for table-esque vertical and horizontal centering */
-.site-wrapper {
- display: table;
- width: 100%;
- height: 100%; /* For at least Firefox */
- min-height: 100%;
-}
-
-.site-wrapper-inner {
- display: table-cell;
- vertical-align: top;
-}
-
-.cover-container {
- margin-right: auto;
- margin-left: auto;
-}
-
-/* Padding for spacing */
-.inner {
- padding: 30px;
}
/*
@@ -106,66 +60,7 @@ body {
float: right;
}
}
-
-/*
- * Cover
- */
-
-.cover {
- padding: 0 20px;
-}
-
-.cover .btn-lg {
- padding: 10px 20px;
- font-weight: bold;
-}
-
-/*
- * Footer
- */
-
-.mastfoot {
- color: #999; /* IE8 proofing */
- color: rgba(255, 255, 255, .5);
-}
-
-/*
- * Affix and center
- */
-
-@media (min-width: 768px) {
- /* Pull out the header and footer */
- .masthead {
- position: fixed;
- top: 0;
- }
-
- .mastfoot {
- position: fixed;
- bottom: 0;
- }
-
- /* Start the vertical centering */
- .site-wrapper-inner {
- vertical-align: middle;
- }
-
- /* Handle the widths */
- .masthead,
- .mastfoot,
- .cover-container {
- width: 100%; /* Must be percentage or pixels for horizontal alignment */
- }
-}
-
-@media (min-width: 992px) {
- .masthead,
- .mastfoot,
- .cover-container {
- width: 700px;
- }
+.container.marketing {
+ padding: 0;
}
-a.btn {
- text-shadow: none;
-}
\ No newline at end of file
diff --git a/core/static/core/css/cover2.css b/core/static/core/css/cover2.css
deleted file mode 100644
index a8c2b03..0000000
--- a/core/static/core/css/cover2.css
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-body {
- padding-top: 20px;
-}
-
-.masthead {
- text-align: center;
- text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
- margin-bottom: 20px;
-
-}
-
-/*
- * Header
- */
-.masthead-brand {
- margin-top: 10px;
- margin-bottom: 10px;
-}
-
-.masthead-nav > li {
- display: inline-block;
-}
-
-.masthead-nav > li + li {
- margin-left: 20px;
-}
-
-.masthead-nav > li > a {
- padding-right: 0;
- padding-left: 0;
- font-size: 16px;
- font-weight: bold;
- color: #333; /* IE8 proofing */
- color: rgba(51, 51, 51, .75);
- border-bottom: 2px solid transparent;
-}
-
-.masthead-nav > li > a:hover,
-.masthead-nav > li > a:focus {
- background-color: transparent;
- color: #333;
- border-bottom-color: rgba(51, 51, 51, .25);
-}
-
-.masthead-nav > .active > a,
-.masthead-nav > .active > a:hover,
-.masthead-nav > .active > a:focus {
- color: #333;
- border-bottom-color: rgba(51, 51, 51, .25);
-}
-
-@media (min-width: 768px) {
- .masthead-brand {
- float: left;
- }
-
- .masthead-nav {
- float: right;
- }
-}
-.container.marketing {
- padding: 0;
-}
-
diff --git a/core/static/core/css/style.css b/core/static/core/css/style.css
index 9083c7e..63aa23b 100644
--- a/core/static/core/css/style.css
+++ b/core/static/core/css/style.css
@@ -113,4 +113,7 @@ a {
.panel-visitors ul>li:first-child {
font-weight: bold;
}
+.btn.btn-block.btn-panel:hover{
+ margin-top: 16px;
+}
diff --git a/core/templates/core/app.html b/core/templates/core/app.html
index d9c4d76..220ba7c 100644
--- a/core/templates/core/app.html
+++ b/core/templates/core/app.html
@@ -1,5 +1,6 @@
{% extends 'core/base.html' %}
{% load staticfiles %}
+{% load djangular_tags %}
{% block title %}Insightful{% endblock %}
{% block base %}
@@ -32,6 +33,9 @@
+
+
+
diff --git a/core/templates/core/base.html b/core/templates/core/base.html
index 9360a45..61b4c97 100644
--- a/core/templates/core/base.html
+++ b/core/templates/core/base.html
@@ -24,7 +24,6 @@
{% block css %}
{% import_django_select2_css %}
-
{% endblock %}
@@ -65,7 +64,7 @@
{% if request.user.is_authenticated %}
diff --git a/engagement/views.py b/engagement/views.py
index 49c8b6f..25aee10 100644
--- a/engagement/views.py
+++ b/engagement/views.py
@@ -15,7 +15,8 @@ def get_data(self, in_data):
@cache_cbv_method_until_midnight
def tracked_content_avg_duration(self):
- interactions = ContentInteraction.objects.values_list('page_view__path', 'content__name')
+ interactions = ContentInteraction.objects.filter(page_view__session__website=self.get_website())
+ interactions = interactions.values_list('page_view__path', 'content__name')
interactions = interactions.filter(page_view__view_timestamp__gte=self.past_timestamp(days=5))
avg_duration_data = interactions.annotate(avg=Avg('duration'))
diff --git a/example/static/js/insightful.min.js b/example/static/js/insightful.min.js
index 9347bc0..8f7878f 100644
--- a/example/static/js/insightful.min.js
+++ b/example/static/js/insightful.min.js
@@ -1,6 +1 @@
-var insightful=function(){function d(a,b){b=b||"active_time";"undefined"===typeof d[b]&&(d[b]=r(function(){var a=b;l(a)?n(a,parseInt(l(a),10)+1):n(a,1)},1E3));d[b]()}function n(a,b,c){c=c||h;m.setItem(c+a,b,Infinity,"/")}function l(a,b){b=b||h;return m.getItem(b+a)}function s(){var a=(new Date).getTime();return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(b){var c=(a+16*Math.random())%16|0;a=Math.floor(a/16);return("x"==b?c:c&7|8).toString(16)})}function t(){var a=l("id","isession_");
-a||(a=s(),n("id",a,"isession_"));for(var a={uuid:a,path:window.location.pathname,id:p},b={},c=m.keys(),f=0;f=l?(clearTimeout(g),g=null,e=k,d=a.apply(c,f)):g||(g=setTimeout(h,l));return d}}var q,p,h="i_",m={getItem:function(a){return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"+encodeURIComponent(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1"))||null},setItem:function(a,b,c,f,d,g){if(!a||/^(?:expires|max\-age|path|domain|secure)$/i.test(a))return!1;var e="";if(c)switch(c.constructor){case Number:e=
-Infinity===c?"; expires=Fri, 31 Dec 9999 23:59:59 GMT":"; max-age="+c;break;case String:e="; expires="+c;break;case Date:e="; expires="+c.toUTCString()}document.cookie=encodeURIComponent(a)+"="+encodeURIComponent(b)+e+(d?"; domain="+d:"")+(f?"; path="+f:"")+(g?"; secure":"");return!0},removeItem:function(a,b,c){if(!a||!this.hasItem(a))return!1;document.cookie=encodeURIComponent(a)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT"+(c?"; domain="+c:"")+(b?"; path="+b:"");return!0},hasItem:function(a){return(new RegExp("(?:^|;\\s*)"+
-encodeURIComponent(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=")).test(document.cookie)},keys:function(){for(var a=document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g,"").split(/\s*(?:\=[^;]*)?;\s*/),b=0;b=l?(clearTimeout(g),g=null,e=k,d=a.apply(c,f)):g||(g=setTimeout(h,l));return d}}var q,p,h="i_",m={getItem:function(a){return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*"+encodeURIComponent(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1"))||null},setItem:function(a,b,c,f,d,g){if(!a||/^(?:expires|max\-age|path|domain|secure)$/i.test(a))return!1;var e="";if(c)switch(c.constructor){case Number:e= Infinity===c?"; expires=Fri, 31 Dec 9999 23:59:59 GMT":"; max-age="+c;break;case String:e="; expires="+c;break;case Date:e="; expires="+c.toUTCString()}document.cookie=encodeURIComponent(a)+"="+encodeURIComponent(b)+e+(d?"; domain="+d:"")+(f?"; path="+f:"")+(g?"; secure":"");return!0},removeItem:function(a,b,c){if(!a||!this.hasItem(a))return!1;document.cookie=encodeURIComponent(a)+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT"+(c?"; domain="+c:"")+(b?"; path="+b:"");return!0},hasItem:function(a){return(new RegExp("(?:^|;\\s*)"+ encodeURIComponent(a).replace(/[\-\.\+\*]/g,"\\$&")+"\\s*\\=")).test(document.cookie)},keys:function(){for(var a=document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g,"").split(/\s*(?:\=[^;]*)?;\s*/),b=0;b
+
{% endblock %}
{% block navbar %}
@@ -18,7 +18,7 @@
diff --git a/website/templates/website/learnmore.html b/website/templates/website/learnmore.html
index c248d71..9ad0f2f 100644
--- a/website/templates/website/learnmore.html
+++ b/website/templates/website/learnmore.html
@@ -115,7 +115,7 @@
{% block css %}
{{ block.super }}
-
+
{% endblock %}
{% block navbar %}