Add hiccup statistic page
diff --git a/crashreports/serializers.py b/crashreports/serializers.py
new file mode 100644
index 0000000..c551198
--- /dev/null
+++ b/crashreports/serializers.py
@@ -0,0 +1,10 @@
+from rest_framework import serializers
+from models import Crashreport
+from rest_framework import permissions
+
+class CrashReportSerializer(serializers.ModelSerializer):
+    permission_classes = (permissions.IsAuthenticated)
+    class Meta:
+        model = Crashreport
+        fields = ('pk','uuid', 'uptime', 'build_fingerprint', 'boot_reason',
+        'power_on_reason', 'power_off_reason', 'aux_data', 'date')
diff --git a/crashreports/static/crashreports/style.css b/crashreports/static/crashreports/style.css
new file mode 100644
index 0000000..8d4af5f
--- /dev/null
+++ b/crashreports/static/crashreports/style.css
@@ -0,0 +1,28 @@
+h2 {
+  margin-top:60px;
+}
+h1 {
+  margin-top:50px;
+}
+
+#container {
+  margin: auto;
+  width: 90%;
+  
+}
+
+div.chart {
+  margin: 5px;
+  width: 500px;
+  height: 500px;
+  float: left;
+  -webkit-box-shadow: 7px 10px 26px 0px rgba(0,0,0,0.15);
+  -moz-box-shadow: 7px 10px 26px 0px rgba(0,0,0,0.15);
+  box-shadow: 7px 10px 26px 0px rgba(0,0,0,0.15);
+}
+
+body { 
+  font-family: sans-serif;
+  text-align: center;
+  background-color: #eee;
+}
diff --git a/crashreports/templates/crashreports/hiccup_stats.html b/crashreports/templates/crashreports/hiccup_stats.html
new file mode 100644
index 0000000..d390324
--- /dev/null
+++ b/crashreports/templates/crashreports/hiccup_stats.html
@@ -0,0 +1,159 @@
+<html>
+<head>
+  <meta charset="utf-8">
+  <META HTTP-EQUIV="refresh" CONTENT="300">
+    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.css" charset="utf-8" >
+    <link rel="stylesheet" type="text/css" href="/static/crashreports/style.css" charset="utf-8" >
+    
+    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
+    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.2/nv.d3.min.js" charset="utf-8"></script>
+    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
+    
+  </head>
+  
+  <body>
+    <h1> Hiccup Stats </h1>
+    <div id="container">
+      <div id = "all_fingerprints" class="chart">
+      </div>
+      <div id = "probable_crashes" class="chart">
+      </div >
+      <div id = "Crash_Distribution" class="chart">
+      </div >
+      <div id = "Crash_Distribution_crashes" class="chart">
+      </div >
+      <div id = "SMPL_chart" class="chart">
+      </div >
+    </div>
+    <script>
+    
+    console.log("test");
+    
+    // Load the Visualization API and the corechart package.
+    google.charts.load('current', {'packages':['corechart']});
+    
+    // Set a callback to run when the Google Visualization API is loaded.
+    google.charts.setOnLoadCallback(drawChart);
+    
+    function aggregate_build_fingerprints(data) {
+      totals = {}
+      data = clear_fake_crashes(data)
+      for (var entry in data) {
+        key = ""
+        if (data[entry].build_fingerprint.includes("a:user")) {
+          key = "DDRFIX";
+        } else {
+          key = "Normal"
+        }
+        if (!totals[key]) {
+          console.log(data[entry].build_fingerprint);
+          totals[key] = 0;
+        } 
+        totals[key] += 1;
+      }
+      ret = []
+      for (var entry in totals) {
+        ret.push([entry, totals[entry]])
+      }
+      return ret;
+    } 
+    
+    function aggregate_uuid(data) {
+      data = clear_fake_crashes(data)
+      totals = {}
+      for (var entry in data) {
+        if (!totals[data[entry].uuid]) {
+          console.log(data[entry].uuid);
+          totals[data[entry].uuid] = 0;
+        } 
+        totals[data[entry].uuid] += 1;
+      }
+      ret = []
+      for (var entry in totals) {
+        ret.push([entry, totals[entry]])
+      }
+      return ret;
+    }
+    
+
+    function clear_fake_crashes(data) {
+      ret = {}
+      for (var entry in data) {
+        if (data[entry].boot_reason=="FAKECRASH") {
+          continue;
+        }
+        ret[entry]=data[entry];
+      }
+      return ret;
+    }
+    
+    function aggregate_SMPL(data) {
+      totals = {}
+      data = clear_fake_crashes(data)
+      for (var entry in data) {
+        key = ""
+        if (data[entry].power_on_reason.includes("SMPL")) {
+          key = "SMPL";
+        } else if (data[entry].power_off_reason.includes("SOFT")) {
+          key = "Crash";        
+        } else {
+          continue;
+        }
+        if (!totals[key]) {
+          console.log(data[entry].build_fingerprint);
+          totals[key] = 0;
+        } 
+        totals[key] += 1;
+      }
+      ret = []
+      for (var entry in totals) {
+        ret.push([entry, totals[entry]])
+      }
+      return ret;
+    } 
+    
+    function drawChart() {
+      drawChartFromDate("2016-09-09","");
+    }
+    
+    function drawChartFromDate(startDate,endDate) {
+      drawChartFingerprints("/hiccup/crashreports/?format=json&start_date="+startDate+"&end_date="+endDate, "All Crashreports", 'all_fingerprints',aggregate_build_fingerprints);
+      drawChartFingerprints("/hiccup/crashreports/?format=json&start_date="+startDate+"&end_date="+endDate+"&boot_reason=keyboard+power+on", "Probable Crashes", 'probable_crashes', aggregate_build_fingerprints);
+      drawChartFingerprints("/hiccup/crashreports/?format=json&start_date="+startDate+"&end_date="+endDate, "SMPL or Crash", 'SMPL_chart', aggregate_SMPL);
+      drawUuidHistogram("/hiccup/crashreports/?format=json&start_date="+startDate+"&end_date="+endDate, "Crash Distribution", 'Crash_Distribution');
+      drawUuidHistogram("/hiccup/crashreports/?format=json&start_date="+startDate+"&end_date="+endDate+"&boot_reason=keyboard+power+on", "Crash Distribution (probable Crashes)", 'Crash_Distribution_crashes');
+    }
+    
+    function drawChartFingerprints(url, title, element, aggregate_function) { $.getJSON( url, function( data ) {
+      var totals_fingerprint = aggregate_function(data);
+      var options = {
+        title: title,
+        pieHole: 0.4,
+      };
+      var chart = new google.visualization.PieChart(document.getElementById(element));
+      var data = new google.visualization.DataTable();
+      data.addColumn('string', 'Build Fingerprint');
+      data.addColumn('number', 'Number of Crashreports');
+      data.addRows(totals_fingerprint);
+      chart.draw(data, options);
+    });
+    }
+  
+  function drawUuidHistogram(url, title, element) { $.getJSON( url, function( data ) {
+    var totals_fingerprint = aggregate_uuid(data);
+    var options = {
+      title: title,
+      pieHole: 0.4,
+    };
+    var chart = new google.visualization.Histogram(document.getElementById(element));
+    var data = new google.visualization.DataTable();
+    data.addColumn('string', 'Build Fingerprint');
+    data.addColumn('number', 'Number of Crashreports');
+    data.addRows(totals_fingerprint);
+    chart.draw(data, options);
+  });
+ }
+</script>
+</body>
+</html>
diff --git a/crashreports/templates/registration/login.html b/crashreports/templates/registration/login.html
new file mode 100644
index 0000000..397eadf
--- /dev/null
+++ b/crashreports/templates/registration/login.html
@@ -0,0 +1,66 @@
+{% extends "admin/base_site.html" %}
+{% load i18n static %}
+
+{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/login.css" %}" />
+{{ form.media }}
+{% endblock %}
+
+{% block bodyclass %}{{ block.super }} login{% endblock %}
+
+{% block usertools %}{% endblock %}
+
+{% block nav-global %}{% endblock %}
+
+{% block content_title %}{% endblock %}
+
+{% block breadcrumbs %}{% endblock %}
+
+{% block content %}
+{% if form.errors and not form.non_field_errors %}
+<p class="errornote">
+{% if form.errors.items|length == 1 %}{% trans "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
+</p>
+{% endif %}
+
+{% if form.non_field_errors %}
+{% for error in form.non_field_errors %}
+<p class="errornote">
+    {{ error }}
+</p>
+{% endfor %}
+{% endif %}
+
+<div id="content-main">
+
+{% if user.is_authenticated %}
+<p class="errornote">
+{% blocktrans trimmed %}
+    You are authenticated as {{ username }}, but are not authorized to
+    access this page. Would you like to login to a different account?
+{% endblocktrans %}
+</p>
+{% endif %}
+
+<form action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
+  <div class="form-row">
+    {{ form.username.errors }}
+    {{ form.username.label_tag }} {{ form.username }}
+  </div>
+  <div class="form-row">
+    {{ form.password.errors }}
+    {{ form.password.label_tag }} {{ form.password }}
+    <input type="hidden" name="next" value="{{ next }}" />
+  </div>
+  {% url 'admin_password_reset' as password_reset_url %}
+  {% if password_reset_url %}
+  <div class="password-reset-link">
+    <a href="{{ password_reset_url }}">{% trans 'Forgotten your password or username?' %}</a>
+  </div>
+  {% endif %}
+  <div class="submit-row">
+    <label>&nbsp;</label><input type="submit" value="{% trans 'Log in' %}" />
+  </div>
+</form>
+
+</div>
+{% endblock %}
diff --git a/crashreports/urls.py b/crashreports/urls.py
index 66ad6e1..e121032 100644
--- a/crashreports/urls.py
+++ b/crashreports/urls.py
@@ -1,7 +1,13 @@
-from django.conf.urls import url
+from django.conf.urls import url, include
 from . import views
+from rest_framework import routers
+from rest_framework import filters
+
+router = routers.DefaultRouter()
+router.register(r'crashreports', views.CrashreportViewSet)
 
 urlpatterns = [
     url(r'^crashreport/', views.index, name='index'),
-    url(r'^get_crash_statistic', views.get_crash_statistic, name='get_crash_statistic'),
-    url(r'', views.empty, name='empty'),]
+    url(r'^crashreports/hiccup_stats/', views.hiccup_stats, name='home'),
+    url(r'^', include(router.urls)),
+]
diff --git a/crashreports/views.py b/crashreports/views.py
index 5beff69..54a09f0 100644
--- a/crashreports/views.py
+++ b/crashreports/views.py
@@ -12,10 +12,21 @@
 
 from django.contrib.auth.decorators import login_required
 from django.db.models import Count
+from rest_framework import viewsets
+from serializers import CrashReportSerializer
+from rest_framework.permissions import BasePermission
+from rest_framework import filters
+from rest_framework import generics
+import django_filters
+from django.template import loader
+
 
 import datetime
 import time
 
+from ratelimit.decorators import ratelimit
+
+@ratelimit( key='ip', rate='100/h')
 @csrf_exempt
 def index(request):
     # Handle file upload`
@@ -40,19 +51,36 @@
         else:
             return HttpResponse(status=400)
     else:
-        return HttpResponse(status=400) 
+        return HttpResponse(status=400)
+
+class IsCreationOrIsAuthenticated(BasePermission):
+    def has_permission(self, request, view):
+        if not request.user.is_authenticated():
+            if view.action == 'create':
+                return True
+            else:
+                return False
+        else:
+            return True
+
+class ListFilter(django_filters.Filter):
+    def filter(self, qs, value):
+        value_list = value.split(u',')
+        return super(ListFilter, self).filter(qs, django_filters.fields.Lookup(value_list, 'in'))
 
 
-def empty(request):
-    return HttpResponse(status=204)
+class CrashreportFilter(filters.FilterSet):
+    start_date = django_filters.DateTimeFilter(name="date", lookup_expr='gte')
+    end_date = django_filters.DateTimeFilter(name="date", lookup_expr='lte')
+    boot_reason = ListFilter(name='boot_reason')
+    class Meta:
+        model = Crashreport
+        fields = ['build_fingerprint','boot_reason', 'power_on_reason', 'power_off_reason']
 
-@login_required
-def get_crash_statistic(request):
-    from_date = request.GET.get('from_date', "2016-01-01")
-    to_date = request.GET.get('to_date', "2017-01-01")
-    entries = Crashreport.objects.filter(date__range=[from_date, to_date]).extra({'date_created' : "date(date)"}).values('date_created').annotate(created_count=Count('id'))
-    for entry in entries:
-        entry['date_created']=time.mktime(datetime.datetime.strptime(entry['date_created'], "%Y-%m-%d").timetuple())*1000
-    return  render_to_response('crashreports/json/crashreport_by_day.html/', {
-        'entries' : entries
-    })
+
+class CrashreportViewSet(viewsets.ModelViewSet):
+    queryset = Crashreport.objects.all()
+    serializer_class =  CrashReportSerializer
+    permission_classes = [IsCreationOrIsAuthenticated]
+    filter_backends = (filters.DjangoFilterBackend,)
+    filter_class = CrashreportFilter