diff options
author | Akshen | 2017-09-25 12:31:24 +0530 |
---|---|---|
committer | Akshen | 2017-09-25 12:31:24 +0530 |
commit | 8a0dcbf56d6a5a8ab389a0879c0da7a426de0d37 (patch) | |
tree | 0a1dcaea3eff5c9a75e3b736f37836622e676e4b /statistics_app | |
parent | 71b2b649629de30ef133ce2dd9c8e855abe66a31 (diff) | |
download | workshop_booking-8a0dcbf56d6a5a8ab389a0879c0da7a426de0d37.tar.gz workshop_booking-8a0dcbf56d6a5a8ab389a0879c0da7a426de0d37.tar.bz2 workshop_booking-8a0dcbf56d6a5a8ab389a0879c0da7a426de0d37.zip |
Adds statistics_app
- Adds statistics_app
- moves workshop_stats to statistics_app
- changes urls of workshop_stats to statistics
- adds public_stats
- modified form.py to get off regex warning
- updates urls.py
Diffstat (limited to 'statistics_app')
-rw-r--r-- | statistics_app/__init__.py | 0 | ||||
-rw-r--r-- | statistics_app/admin.py | 3 | ||||
-rw-r--r-- | statistics_app/apps.py | 5 | ||||
-rw-r--r-- | statistics_app/models.py | 3 | ||||
-rw-r--r-- | statistics_app/templates/statistics_app/workshop_public_stats.html | 353 | ||||
-rw-r--r-- | statistics_app/templates/statistics_app/workshop_stats.html | 394 | ||||
-rw-r--r-- | statistics_app/tests.py | 3 | ||||
-rw-r--r-- | statistics_app/urls.py | 12 | ||||
-rw-r--r-- | statistics_app/views.py | 455 |
9 files changed, 1228 insertions, 0 deletions
diff --git a/statistics_app/__init__.py b/statistics_app/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/statistics_app/__init__.py diff --git a/statistics_app/admin.py b/statistics_app/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/statistics_app/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/statistics_app/apps.py b/statistics_app/apps.py new file mode 100644 index 0000000..1a4799b --- /dev/null +++ b/statistics_app/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class StatisticsAppConfig(AppConfig): + name = 'statistics_app' diff --git a/statistics_app/models.py b/statistics_app/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/statistics_app/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/statistics_app/templates/statistics_app/workshop_public_stats.html b/statistics_app/templates/statistics_app/workshop_public_stats.html new file mode 100644 index 0000000..8894037 --- /dev/null +++ b/statistics_app/templates/statistics_app/workshop_public_stats.html @@ -0,0 +1,353 @@ +{% extends 'workshop_app/base.html' %} + +{% block header %} + <nav class="navbar navbar-default navbar-custom"> + <div class="container-fluid"> + <div class="navbar-header"> + <a class="navbar-brand" href="{{ URL_ROOT }}/">Home</a> + </div> + <ul class="nav navbar-nav navbar-right"> + <li><a href="{{ URL_ROOT }}/register/"><span class="glyphicon glyphicon-user"></span>Register</a></li> + <li><a href="{{ URL_ROOT }}/login/"><span class="glyphicon glyphicon-log-in"></span>Login</a></li> + </ul> + </div> + </nav> +{% endblock %} + +{% block extra %} + <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> + <script src="https://code.jquery.com/jquery-1.12.4.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> + <!-- For Charts --> + + <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.min.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script> + + <!-- For Google GeoChart India Map --> + <script type='text/javascript' src='https://www.google.com/jsapi'></script> + +<script> + var dateToday = new Date(); + var upto = new Date(); + + dateToday.setDate(dateToday.getDate() - 1); + upto.setFullYear(dateToday.getFullYear() + 1); + + $( function() { + from = $( "#from" ) + .datepicker({ + defaultDate: "+1w", + changeMonth: true, + changeYear: true, + showButtonPanel: true, + maxDate: dateToday, + dateFormat: "yy-mm-dd" + }) + .on( "change", function() { + to.datepicker( "option", "minDate", getDate( this ) ); + }), + to = $( "#to" ).datepicker({ + defaultDate: "+1w", + changeMonth: true, + changeYear: true, + showButtonPanel: true, + minDate: dateToday, + maxDate: upto, + dateFormat: "yy-mm-dd" + }) + .on( "change", function() { + from.datepicker( "option", "maxDate", getDate( this ) ); + }); + + function getDate( element ) { + var date; + try { + date = $.datepicker.parseDate( dateFormat, element.value ); + } catch( error ) { + date = null; + } + return date; + } + } ); + + </script> + +{% endblock %} + +{% block content %} + +<div class="container"> + <div class="row"> + <div class="col-md-4" align="left" > + <fieldset data-mini="true"> + <label for="radio-2">Overall Count</label> + <input type="radio" name="radio-1" id="radio-2" value="OWC"> + <label for="radio-3">India Map</label> + <input type="radio" name="radio-1" id="radio-3" value="MOIN"> + </fieldset> + </div> + + <div class="col-md-8"> + <form method="POST" > + {% csrf_token %} + <div class="form-group"> + <label>state: </label> + <select name="states"> + <option value="all">ALL</option> + <option value="IN-AP">Andhra Pradesh</option> + <option value="IN-AR">Arunachal Pradesh</option> + <option value="IN-AS">Assam</option> + <option value="IN-BR">Bihar</option> + <option value="IN-CT">Chhattisgarh</option> + <option value="IN-GA">Goa</option> + <option value="IN-GJ">Gujarat</option> + <option value="IN-HR">Haryana</option> + <option value="IN-HP">Himachal Pradesh</option> + <option value="IN-JK">Jammu and Kashmir</option> + <option value="IN-JH">Jharkhand</option> + <option value="IN-KA">Karnataka</option> + <option value="IN-KL">Kerala</option> + <option value="IN-MP">Madhya Pradesh</option> + <option value="IN-MH">Maharashtra</option> + <option value="IN-MN">Manipur</option> + <option value="IN-ML">Meghalaya</option> + <option value="IN-MZ">Mizoram</option> + <option value="IN-NL">Nagaland</option> + <option value="IN-OR">Odisha</option> + <option value="IN-PB">Punjab</option> + <option value="IN-RJ">Rajasthan</option> + <option value="IN-SK">Sikkim</option> + <option value="IN-TN">Tamil Nadu</option> + <option value="IN-TG">Telangana</option> + <option value="IN-TR">Tripura</option> + <option value="IN-UT">Uttarakhand</option> + <option value="IN-UP">Uttar Pradesh</option> + <option value="IN-WB">West Bengal</option> + <option value="IN-AN">Andaman and Nicobar Islands</option> + <option value="IN-CH">Chandigarh</option> + <option value="IN-DN">Dadra and Nagar Haveli</option> + <option value="IN-DD">Daman and Diu</option> + <option value="IN-DL">Delhi</option> + <option value="IN-LD">Lakshadweep</option> + <option value="IN-PY">Puducherry</option> + </select> + <label>WorkshopType: </label> + <select name="workshoptype_name"> + {% for workshop in workshoptype_list %} + <option value={{ workshop.id }}> {{ workshop }} </option> + {% endfor %} + </select> + + <br> + <label for="from">From</label> + <input type="text" id="from" name="from"> + <label for="to">to</label> + <input type="text" id="to" name="to"> + <button class="btn btn-info btn-sm" type="submit" name="View" value="View">View</button> + </div> + </form> + + {% if messages %} + <ul class="messages"> + {% for message in messages %} + <div class="alert alert-{{ message.tags }}"> + <li {% if message.tags %} class="{{ message.tags }}"{% endif %}> {{ message }} + </li> + </div> + {% endfor %} + </ul> + {% endif %} + + </div> + <br> + <table class="table table-hover"> + <thead> + <tr> + <th>Coordinator Name</th> + <th>Institute Name</th> + <th>Instructor Name</th> + <th>Workshop Name</th> + <th>Workshop Date</th> + <th>Initiated By</th> + </tr> + </thead> + {% csrf_token %} + {% for workshop in workshop_list %} + {% if workshop.proposed_workshop_date %} + <tbody> + <tr> + <td>{{ workshop.proposed_workshop_coordinator.get_full_name | capfirst }}</td> + <td>{{ workshop.proposed_workshop_coordinator.profile.institute | capfirst }}</td> + <td>{{ workshop.proposed_workshop_instructor.get_full_name }}</td> + <td>{{ workshop.proposed_workshop_title.workshoptype_name }}</td> + <td>{{ workshop.proposed_workshop_date | date}}</td> + <td>Coordinator</td> + </tr> + </tbody> + {% else %} + <tbody> + <tr> + <td>{{ workshop.requested_workshop_coordinator.get_full_name | capfirst }}</td> + <td>{{ workshop.requested_workshop_coordinator.profile.institute | capfirst }}</td> + <td>{{ workshop.requested_workshop_instructor.get_full_name }}</td> + <td>{{ workshop.requested_workshop_title.workshoptype_name }}</td> + <td>{{ workshop.requested_workshop_date | date}}</td> + <td>Instructor</td> + </tr> + </tbody> + {% endif %} + {% endfor %} + </table> + + <!-- Page Navigation --> + <div class="container"> + <div class="Page-Nav" align="center"> + <nav aria-label="Page navigation"> + <ul class="pagination pagination-sm"> + <li class="page-item"> + {% if workshop_list.has_previous %} + <a class="page-link" tabindex="-1" + href="?page={{ workshop_list.previous_page_number }}">Previous</a> + {% endif %} + </li> + <li class="page-item"> + <span class="current"> + Page {{ workshop_list.number }} of {{ workshop_list.paginator.num_pages }} + </span> + </li> + <li class="page-item"> + {% if workshop_list.has_next %} + <a class="page-link" href="?page={{ workshop_list.next_page_number }}">Next + </a> + {% endif %} + </li> + </ul> + </nav> + </div> + </div> + </div> + +<div class="row"> + <br> + <div class="col-md-12 "> + <br> + <canvas id="myChartPie" ></canvas> + <script> + $( function() { + $( "fieldset" ).controlgroup(); + }); + + var ctx1 = document.getElementById("myChartPie").getContext('2d'); + var myChart; + + $('input[type=radio]').change(function() { + if (this.value == 'OWC') { //Overall Workshop Count + if(myChart){ + myChart.destroy(); + } + + var dWidth = $(window).width() * 0.9; + var dHeight = $(window).height() * 0.9; + + $( "#myChartPie" ).dialog({ + resizable: false, + draggable: true, + title: 'Pie Chart', + closeOnEscape: true, + stack: true, + zIndex: 10000, + width: dWidth, + height: dHeight, + modal: true + }); + + document.getElementById("visualization").style.visibility='hidden'; + myChart = new Chart(ctx1, { + type: 'pie', + data: { + labels : {{ workshoptype_count.0 | safe}}, + datasets: [{ + data: {{ workshoptype_count.1 }}, + //Add more color scheme if workshop number increases + backgroundColor: [ + 'rgba(153, 102, 255, 1)', + 'rgba(191, 191, 1, 1)', + 'rgba(75, 192, 192, 1)', + 'rgba(153, 102, 255, 1)' + ] + }] + }, + options: { + responsive: true + } + }); + } + + else if (this.value == 'MOIN') { + if(myChart){ + myChart.destroy(); + } + + var dWidth = $(window).width() * 0.9; + var dHeight = $(window).height() * 0.9; + + $( "#visualization" ).dialog({ + resizable: false, + draggable: true, + title: 'Map of India', + closeOnEscape: true, + stack: true, + zIndex: 10000, + width: dWidth, + height: dHeight, + modal: true + }); + + document.getElementById("visualization").style.visibility='visible'; + function drawVisualization() { + var data = google.visualization.arrayToDataTable( + {{ india_map | safe }} + ); + + var opts = { + region: 'IN', + domain: 'IN', + displayMode: 'regions', + resolution: 'provinces', + colorAxis: {colors: ['lightyellow', 'orange']}, + legend: {position: 'top'}, + }; + + var geochart = new google.visualization.GeoChart( + document.getElementById('visualization')); + geochart.draw(data, opts); + }; + if(google) { + google.load('visualization', '1.0', { + packages: ['geochart'], + callback: function() { + // do stuff, if you wan't - it doesn't matter, because the page isn't blank! + drawVisualization(); + } + }) + } + } + }); + </script> + <style> + #visualization path { + stroke-width:1; /* control the countries borders width */ + stroke:#6699cc; /* choose a color for the border */ + } + </style> + <div id="visualization" style="width: 400px; height: 300px; display: block; margin: 0 auto;" ></div> + + </div> +</div> +</div> +<br> +{% endblock %} diff --git a/statistics_app/templates/statistics_app/workshop_stats.html b/statistics_app/templates/statistics_app/workshop_stats.html new file mode 100644 index 0000000..ba597dc --- /dev/null +++ b/statistics_app/templates/statistics_app/workshop_stats.html @@ -0,0 +1,394 @@ +{% extends 'workshop_app/base.html' %} + +{% block header %} + <nav class="navbar navbar-default navbar-custom"> + <div class="container-fluid"> + <div class="navbar-header"> + <a class="navbar-brand" href="{{ URL_ROOT }}/manage/">Home</a> + </div> + <ul class="nav navbar-nav"> + <li ><a href="{{ URL_ROOT }}/create_workshop/">Create Workshop</a></li> + <li ><a href="{{ URL_ROOT }}/view_workshoptype_list/"> Workshop List</a></li> + <li ><a href="{{ URL_ROOT }}/my_workshops/">My Workshops</a></li> + <li class="active"><a href="{{ URL_ROOT }}/workshop_stats/" >Workshop Stats</a></li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li><a href="{{ URL_ROOT }}/view_profile/"><span class="glyphicon glyphicon-user"></span> Profile </a></li> + <li><a href="{{ URL_ROOT }}/logout/"><span class="glyphicon glyphicon-log-out"></span> Logout</a></li> + </ul> + </div> + </nav> +{% endblock %} + +{% block extra %} + <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> + <script src="https://code.jquery.com/jquery-1.12.4.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> + + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> + <!-- For Charts --> + + <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.min.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script> + + <!-- For Google GeoChart India Map --> + <script type='text/javascript' src='https://www.google.com/jsapi'></script> + +<script> + var dateToday = new Date(); + var upto = new Date(); + + dateToday.setDate(dateToday.getDate() - 1); + upto.setFullYear(dateToday.getFullYear() + 1); + + $( function() { + from = $( "#from" ) + .datepicker({ + defaultDate: "+1w", + changeMonth: true, + changeYear: true, + showButtonPanel: true, + maxDate: dateToday, + dateFormat: "yy-mm-dd" + }) + .on( "change", function() { + to.datepicker( "option", "minDate", getDate( this ) ); + }), + to = $( "#to" ).datepicker({ + defaultDate: "+1w", + changeMonth: true, + changeYear: true, + showButtonPanel: true, + minDate: dateToday, + maxDate: upto, + dateFormat: "yy-mm-dd" + }) + .on( "change", function() { + from.datepicker( "option", "maxDate", getDate( this ) ); + }); + + function getDate( element ) { + var date; + try { + date = $.datepicker.parseDate( dateFormat, element.value ); + } catch( error ) { + date = null; + } + return date; + } + } ); + + </script> + +{% endblock %} + +{% block content %} + +<div class="container"> + <div class="row"> + <div class="col-md-6" align="left" > + <fieldset data-mini="true"> + <label for="radio-1">Monthly Count </label> + <input type="radio" name="radio-1" id="radio-1" value="NWPM"> + <label for="radio-2">Overall Count</label> + <input type="radio" name="radio-1" id="radio-2" value="OWC"> + <label for="radio-3">India Map</label> + <input type="radio" name="radio-1" id="radio-3" value="MOIN"> + </fieldset> + </div> + + + {% if show_workshop_stats %} + <div align="right" class="col-md-6"> + <form method="POST" > + {% csrf_token %} + <div class="form-group"> + <label for="from">From</label> + <input type="text" id="from" name="from"> + <label for="to">to</label> + <input type="text" id="to" name="to"> + <button class="btn btn-warning btn-sm" type="submit" name="Download" value="Download">Download</button> + <button class="btn btn-info btn-sm" type="submit" name="View" value="View">View</button> + </div> + </form> + + {% if messages %} + <ul class="messages"> + {% for message in messages %} + <div class="alert alert-{{ message.tags }}"> + <li {% if message.tags %} class="{{ message.tags }}"{% endif %}> {{ message }} + </li> + </div> + {% endfor %} + </ul> + {% endif %} + + </div> + <br> + <table class="table table-hover"> + <thead> + <tr> + <th>Coordinator Name</th> + <th>Institute Name</th> + <th>Instructor Name</th> + <th>Workshop Name</th> + <th>Workshop Date</th> + <th>Requested/Proposed By</th> + </tr> + </thead> + {% csrf_token %} + {% for workshop in upcoming_workshops %} + {% if workshop.proposed_workshop_date %} + <tbody> + <tr> + <td>{{ workshop.proposed_workshop_coordinator.get_full_name | capfirst }}</td> + <td>{{ workshop.proposed_workshop_coordinator.profile.institute | capfirst }}</td> + <td>{{ workshop.proposed_workshop_instructor.get_full_name }}</td> + <td>{{ workshop.proposed_workshop_title.workshoptype_name }}</td> + <td>{{ workshop.proposed_workshop_date | date}}</td> + <td>Coordinator</td> + </tr> + </tbody> + {% else %} + <tbody> + <tr> + <td>{{ workshop.requested_workshop_coordinator.get_full_name | capfirst }}</td> + <td>{{ workshop.requested_workshop_coordinator.profile.institute | capfirst }}</td> + <td>{{ workshop.requested_workshop_instructor.get_full_name }}</td> + <td>{{ workshop.requested_workshop_title.workshoptype_name }}</td> + <td>{{ workshop.requested_workshop_date | date}}</td> + <td>Instructor</td> + </tr> + </tbody> + {% endif %} + {% endfor %} + </table> + + <!-- Page Navigation --> + <div class="container"> + <div class="Page-Nav" align="center"> + <nav aria-label="Page navigation"> + <ul class="pagination pagination-sm"> + <li class="page-item"> + {% if upcoming_workshops.has_previous %} + <a class="page-link" tabindex="-1" + href="?page={{ upcoming_workshops.previous_page_number }}">Previous</a> + {% endif %} + </li> + <li class="page-item"> + <span class="current"> + Page {{ upcoming_workshops.number }} of {{ upcoming_workshops.paginator.num_pages }} + </span> + </li> + <li class="page-item"> + {% if upcoming_workshops.has_next %} + <a class="page-link" href="?page={{ upcoming_workshops.next_page_number }}">Next + </a> + {% endif %} + </li> + </ul> + </nav> + </div> + </div> + {% else %} + <div class="jumbotron"> + <h2>Permission to View Upcoming Workshops is set to false, please set it to true in settings.py</h2> + </div> + {% endif %} + </div> + + +<div class="row"> + <br> + <div class="col-md-12 "> + <br> + <canvas id="myChartPie" ></canvas> + <script> + $( function() { + $( "fieldset" ).controlgroup(); + }); + + var ctx1 = document.getElementById("myChartPie").getContext('2d'); + var myChart; + + $('input[type=radio]').change(function() { + + if (this.value == 'NWPM') {//Number of Workshops per month + if(myChart){ + myChart.destroy(); + } + + var dWidth = $(window).width() * 0.9; + var dHeight = $(window).height() * 0.9; + + $( "#myChartPie" ).dialog({ + resizable: false, + draggable: true, + title: 'Bar Chart', + closeOnEscape: true, + stack: true, + zIndex: 10000, + width: dWidth, + height: dHeight, + modal: true + }); + + document.getElementById("visualization").style.visibility='hidden'; + myChart = new Chart(ctx1, { + type: 'bar', + data: { + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', ' December'], + datasets: [{ + label: 'Number of workshops per Month for '+ dateToday.getFullYear(), + data: {{ workshop_count }}, + backgroundColor: [ + 'rgba(255, 99, 132, 0.2)', + 'rgba(54, 162, 235, 0.2)', + 'rgba(255, 206, 86, 0.2)', + 'rgba(75, 192, 192, 0.2)', + 'rgba(153, 102, 255, 0.2)', + 'rgba(242, 38, 19, 0.2)', + 'rgba(25, 91, 13, 0.2)', + 'rgba(54, 12, 235, 0.2)', + 'rgba(150, 40, 27, 0.2)', + 'rgba(66, 114, 155, 0.2)', + 'rgba(219, 10, 91, 0.2)', + 'rgba(191, 191, 191, 0.2)' + ], + borderColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + 'rgba(255, 206, 86, 1)', + 'rgba(75, 192, 192, 1)', + 'rgba(153, 102, 255, 1)', + 'rgba(242, 38, 19, 1)', + 'rgba(25, 91, 13, 1)', + 'rgba(54, 12, 235, 1)', + 'rgba(150, 40, 27 ,1)', + 'rgba(66, 114, 155, 1)', + 'rgba(219, 10, 91, 1)', + 'rgba(191, 191, 191, 1)' + ], + borderWidth: 1 + }] + }, + options: { + responsive: true, + scales: { + yAxes: [{ + ticks: { + beginAtZero:true + } + }] + } + } + }); + } + else if (this.value == 'OWC') { //Overall Workshop Count + if(myChart){ + myChart.destroy(); + } + + var dWidth = $(window).width() * 0.9; + var dHeight = $(window).height() * 0.9; + + $( "#myChartPie" ).dialog({ + resizable: false, + draggable: true, + title: 'Pie Chart', + closeOnEscape: true, + stack: true, + zIndex: 10000, + width: dWidth, + height: dHeight, + modal: true + }); + + document.getElementById("visualization").style.visibility='hidden'; + myChart = new Chart(ctx1, { + type: 'pie', + data: { + labels : {{ workshoptype_count.0 | safe}}, + datasets: [{ + data: {{ workshoptype_count.1 }}, + //Add more color scheme if workshop number increases + backgroundColor: [ + 'rgba(153, 102, 255, 1)', + 'rgba(191, 191, 1, 1)', + 'rgba(75, 192, 192, 1)', + 'rgba(153, 102, 255, 1)' + ] + }] + }, + options: { + responsive: true + } + }); + } + + else if (this.value == 'MOIN') { + if(myChart){ + myChart.destroy(); + } + + var dWidth = $(window).width() * 0.9; + var dHeight = $(window).height() * 0.9; + + $( "#visualization" ).dialog({ + resizable: false, + draggable: true, + title: 'Map of India', + closeOnEscape: true, + stack: true, + zIndex: 10000, + width: dWidth, + height: dHeight, + modal: true + }); + + document.getElementById("visualization").style.visibility='visible'; + function drawVisualization() { + var data = google.visualization.arrayToDataTable( + {{ india_map | safe }} + ); + + var opts = { + region: 'IN', + domain: 'IN', + displayMode: 'regions', + resolution: 'provinces', + colorAxis: {colors: ['lightyellow', 'orange']}, + legend: {position: 'top'}, + }; + + var geochart = new google.visualization.GeoChart( + document.getElementById('visualization')); + geochart.draw(data, opts); + }; + if(google) { + google.load('visualization', '1.0', { + packages: ['geochart'], + callback: function() { + // do stuff, if you wan't - it doesn't matter, because the page isn't blank! + drawVisualization(); + } + }) + } + } + }); + </script> + <style> + #visualization path { + stroke-width:1; /* control the countries borders width */ + stroke:#6699cc; /* choose a color for the border */ + } + </style> + <div id="visualization" style="width: 400px; height: 300px; display: block; margin: 0 auto;" ></div> + + </div> +</div> +</div> +<br> +{% endblock %} diff --git a/statistics_app/tests.py b/statistics_app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/statistics_app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/statistics_app/urls.py b/statistics_app/urls.py new file mode 100644 index 0000000..a846192 --- /dev/null +++ b/statistics_app/urls.py @@ -0,0 +1,12 @@ + +from django.conf.urls import url +from django.contrib import admin +from statistics_app import views +import django + + + +urlpatterns = [ + url(r'^statistics/$', views.workshop_stats), + url(r'^statistics/public_stats/$', views.workshop_public_stats), +] diff --git a/statistics_app/views.py b/statistics_app/views.py new file mode 100644 index 0000000..be79a78 --- /dev/null +++ b/statistics_app/views.py @@ -0,0 +1,455 @@ +from workshop_app.forms import ( + UserRegistrationForm, UserLoginForm, + ProfileForm, CreateWorkshop, + ProposeWorkshopDateForm +) +from workshop_app.models import ( + Profile, User, + has_profile, Workshop, + WorkshopType, RequestedWorkshop, + BookedWorkshop, ProposeWorkshopDate, + Testimonial +) +from django.template.loader import get_template +from django.template import RequestContext +from datetime import datetime, date +from django.contrib.auth import login, logout, authenticate +from django.contrib.auth.decorators import login_required +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger +from django.shortcuts import render, redirect +from django.db import IntegrityError +from django.utils import timezone +from django.http import HttpResponse, HttpResponseRedirect +from django.conf import settings +from os import listdir, path, sep +from zipfile import ZipFile +from django.contrib import messages +import datetime as dt +import csv +try: + from StringIO import StringIO as string_io +except ImportError: + from io import BytesIO as string_io + + +# Create your views here. +def check_workshop_type(x): + try: + y = datetime.strftime(x.proposed_workshop_date, '%d-%m-%Y') + except BaseException: + y = datetime.strftime(x.requested_workshop_date, '%d-%m-%Y') + return y + + +def is_instructor(user): + '''Check if the user is having instructor rights''' + return True if user.groups.filter(name='instructor').count() > 0 else False + + +def is_email_checked(user): + if hasattr(user, 'profile'): + return True if user.profile.is_email_verified else False + else: + return False + + +def pie_chart(): + '''This function gives Data for drawring Pie Chart''' + + # Count Total Number of workshops for each type + workshop_titles = WorkshopType.objects.all() + workshoptype_dict = {} + for title in workshop_titles: + workshoptype_dict[title] = 0 + + for title in workshoptype_dict.keys(): + workshoptype_dict[title] += RequestedWorkshop.objects.filter( + requested_workshop_title=title, + status='ACCEPTED').count() + workshoptype_dict[title] += ProposeWorkshopDate.objects.filter( + proposed_workshop_title=title, + status='ACCEPTED').count() + + # For Pie Chart + workshoptype_num = [] + workshoptype_title = [] + for title in workshoptype_dict.keys(): + workshoptype_title.append(str(title)) + + for count in workshoptype_dict.values(): + workshoptype_num.append(count) + + workshoptype_count = [workshoptype_title, workshoptype_num] + del workshoptype_title, workshoptype_num + + return workshoptype_count + + + +def india_map(): + '''This function returns count of workshops based on states in India.''' + + states = [ + ['Code', 'State', 'Number'], + ["IN-AP", "Andhra Pradesh", 0], + ["IN-AR", "Arunachal Pradesh", 0], + ["IN-AS", "Assam", 0], + ["IN-BR", "Bihar", 0], + ["IN-CT", "Chhattisgarh", 0], + ["IN-GA", "Goa", 0], + ["IN-GJ", "Gujarat", 0], + ["IN-HR", "Haryana", 0], + ["IN-HP", "Himachal Pradesh", 0], + ["IN-JK", "Jammu and Kashmir", 0], + ["IN-JH", "Jharkhand", 0], + ["IN-KA", "Karnataka", 0], + ["IN-KL", "Kerala", 0], + ["IN-MP", "Madhya Pradesh", 0], + ["IN-MH", "Maharashtra", 0], + ["IN-MN", "Manipur", 0], + ["IN-ML", "Meghalaya", 0], + ["IN-MZ", "Mizoram", 0], + ["IN-NL", "Nagaland", 0], + ["IN-OR", "Odisha", 0], + ["IN-PB", "Punjab", 0], + ["IN-RJ", "Rajasthan", 0], + ["IN-SK", "Sikkim", 0], + ["IN-TN", "Tamil Nadu", 0], + ["IN-TG", "Telangana", 0], + ["IN-TR", "Tripura", 0], + ["IN-UT", "Uttarakhand", 0], + ["IN-UP", "Uttar Pradesh", 0], + ["IN-WB", "West Bengal", 0], + ["IN-AN", "Andaman and Nicobar Islands", 0], + ["IN-CH", "Chandigarh", 0], + ["IN-DN", "Dadra and Nagar Haveli", 0], + ["IN-DD", "Daman and Diu", 0], + ["IN-DL", "Delhi", 0], + ["IN-LD", "Lakshadweep", 0], + ["IN-PY", "Puducherry", 0] + ] + workshop_state = [] + requestedWorkshops = RequestedWorkshop.objects.filter(status='ACCEPTED') + proposedWorkshops = ProposeWorkshopDate.objects.filter(status='ACCEPTED') + for workshop in requestedWorkshops: + for s in states: + if s[0] == workshop.requested_workshop_coordinator.profile.state: + s[2] += 1 + + for workshop in proposedWorkshops: + for s in states: + if s[0] == workshop.proposed_workshop_coordinator.profile.state: + s[2] += 1 + + return states + + + +@login_required +def workshop_stats(request): + user = request.user + today = datetime.now() + upto = today + dt.timedelta(days=15) + + # For Monthly Chart + workshop_count = [0] * 12 + for x in range(12): + workshop_count[x] += RequestedWorkshop.objects.filter( + requested_workshop_date__year=str(today.year), + requested_workshop_date__month=str(x + 1), + status='ACCEPTED').count() + workshop_count[x] += ProposeWorkshopDate.objects.filter( + proposed_workshop_date__year=str(today.year), + proposed_workshop_date__month=str(x + 1), + status='ACCEPTED').count() + + # For Pie Chart + workshoptype_count = pie_chart() + + # For India Map + states = india_map() + + # For Data Downloading and Viewing + if request.method == 'POST': + try: + from_dates = request.POST.get('from') + to_dates = request.POST.get('to') + + # Fetches Accepted workshops which were proposed by Coordinators + proposed_workshops = ProposeWorkshopDate.objects.filter( + proposed_workshop_date__range=(from_dates, to_dates), + status='ACCEPTED' + ) + + # Fetches Accepted workshops which were Accepted by + # Instructors based on their Availability + requested_workshops = RequestedWorkshop.objects.filter( + requested_workshop_date__range=(from_dates, to_dates), + status='ACCEPTED' + ) + + upcoming_workshops = [] + + for workshop in proposed_workshops: + upcoming_workshops.append(workshop) + + for workshop in requested_workshops: + upcoming_workshops.append(workshop) + + upcoming_workshops = sorted(upcoming_workshops, + key=lambda x: check_workshop_type(x)) + + download = request.POST.get('Download') + if download: + response = HttpResponse(content_type='text/csv') + + response['Content-Disposition'] = 'attachment;\ + filename="records_from_{0}_to_{1}.csv"'.format( + from_dates, to_dates + ) + + writer = csv.writer(response) + header = [ + 'coordinator name', + 'instructor name', + 'workshop', + 'date', + 'status', + 'institute name' + ] + + writer.writerow(header) + + for workshop in upcoming_workshops: + try: + row = [ + workshop.proposed_workshop_coordinator, + workshop.proposed_workshop_instructor, + workshop.proposed_workshop_title, + workshop.proposed_workshop_date, + workshop.status, + workshop.proposed_workshop_coordinator.profile.institute] + + except BaseException: + row = [ + workshop.requested_workshop_coordinator, + workshop.requested_workshop_instructor, + workshop.requested_workshop_title, + workshop.requested_workshop_date, + workshop.status, + workshop.requested_workshop_coordinator.profile.institute] + + writer.writerow(row) + return response + else: + return render(request, + 'statistics_app/workshop_stats.html', + {"upcoming_workshops": upcoming_workshops, + "show_workshop_stats": settings.SHOW_WORKSHOP_STATS, + "workshop_count": workshop_count, + "workshoptype_count": workshoptype_count, + "india_map": states}) + except BaseException: + messages.info(request, 'Please enter Valid Dates') + + if is_instructor(user) and is_email_checked(user): + try: + # Fetches Accepted workshops which were proposed by Coordinators + proposed_workshops = ProposeWorkshopDate.objects.filter( + proposed_workshop_date__range=(today, upto), + status='ACCEPTED' + ) + + # Fetches Accepted workshops which were Accepted by + # Instructors based on their Availability + requested_workshops = RequestedWorkshop.objects.filter( + requested_workshop_date__range=(today, upto), + status='ACCEPTED' + ) + + upcoming_workshops = [] + for workshop in proposed_workshops: + upcoming_workshops.append(workshop) + + for workshop in requested_workshops: + upcoming_workshops.append(workshop) + + upcoming_workshops = sorted(upcoming_workshops, + key=lambda x: check_workshop_type(x)) + + except BaseException: + upcoming_workshops = [] + + paginator = Paginator(upcoming_workshops, 12) + + page = request.GET.get('page') + try: + upcoming_workshops = paginator.page(page) + except PageNotAnInteger: + # If page is not an integer, deliver first page. + upcoming_workshops = paginator.page(1) + except EmptyPage: + # If page is out of range(e.g 999999), deliver last page. + upcoming_workshops = paginator.page(paginator.num_pages) + + return render(request, 'statistics_app/workshop_stats.html', + { + "upcoming_workshops": upcoming_workshops, + "show_workshop_stats": settings.SHOW_WORKSHOP_STATS, + "workshop_count": workshop_count, + "workshoptype_count": workshoptype_count, + "india_map": states + }) + else: + return redirect('/statistics/public_stats/') + + +def workshop_public_stats(request): + user = request.user + today = datetime.now() + upto = today + dt.timedelta(days=15) + + #For Pie Chart + workshoptype_count = pie_chart() + + # For India Map + states = india_map() + + # Select By WorkshopType + workshoptype_list = list(WorkshopType.objects.all()) + workshoptype_list.append('all') + + # For Data Viewing + if request.method == 'POST': + workshop_list = [] + + try: + from_dates = request.POST.get('from') + to_dates = request.POST.get('to') + selected_state = request.POST.get('states') + selected_workshoptype = request.POST.get('workshoptype_name') + if selected_state == 'all': + # If dates not passed + if len(from_dates) == 0 and len(to_dates) == 0: + from_dates = '2017-01-01' + to_dates = upto + # If SelectedWorkshopType is 'All' + if len(selected_workshoptype) == 0: + # Fetches Accepted workshops which were proposed by + # Coordinators + proposed_workshops = ProposeWorkshopDate.objects.filter( + proposed_workshop_date__range=(from_dates, to_dates), + status='ACCEPTED' + ) + + # Fetches Accepted workshops which were Accepted by + # Instructors based on their Availability + requested_workshops = RequestedWorkshop.objects.filter( + requested_workshop_date__range=(from_dates, to_dates), + status='ACCEPTED' + ) + + else: + # Fetches Accepted workshops which were proposed by + # Coordinators + proposed_workshops = ProposeWorkshopDate.objects.filter( + proposed_workshop_date__range=(from_dates, to_dates), + status='ACCEPTED', proposed_workshop_title_id=int(selected_workshoptype) + ) + + # Fetches Accepted workshops which were Accepted by + # Instructors based on their Availability + requested_workshops = RequestedWorkshop.objects.filter( + requested_workshop_date__range=(from_dates, to_dates), + status='ACCEPTED', requested_workshop_title_id=int(selected_workshoptype) + ) + + for workshop in proposed_workshops: + workshop_list.append(workshop) + + for workshop in requested_workshops: + workshop_list.append(workshop) + + else: + # If dates not passed + if len(from_dates) == 0 and len(to_dates) == 0: + from_dates = '2017-01-01' + to_dates = upto + + # Get list of coordinators + coordinators_state_wise = Profile.objects.filter( + state=selected_state) + + if len(selected_workshoptype) == 0: + # Traverse through list of coordinators and append + # workshop_list + for coordinator in coordinators_state_wise: + # Fetches Accepted workshops which were proposed by + # Coordinators + proposed_workshops = ProposeWorkshopDate.objects.filter( + proposed_workshop_date__range=( + from_dates, + to_dates), + status='ACCEPTED', + proposed_workshop_coordinator=coordinator.user_id) + + # Fetches Accepted workshops which were Accepted by + # Instructors based on their Availability + requested_workshops = RequestedWorkshop.objects.filter( + requested_workshop_date__range=( + from_dates, + to_dates), + status='ACCEPTED', + requested_workshop_coordinator=coordinator.user_id) + + for workshop in proposed_workshops: + workshop_list.append(workshop) + + for workshop in requested_workshops: + workshop_list.append(workshop) + + else: + # Traverse through list of coordinators and append + # workshop_list + for coordinator in coordinators_state_wise: + # Fetches Accepted workshops which were proposed by + # Coordinators + proposed_workshops = ProposeWorkshopDate.objects.filter( + proposed_workshop_date__range=( + from_dates, + to_dates), + status='ACCEPTED', proposed_workshop_title_id=int(selected_workshoptype), + proposed_workshop_coordinator=coordinator.user_id) + + # Fetches Accepted workshops which were Accepted by + # Instructors based on their Availability + requested_workshops = RequestedWorkshop.objects.filter( + requested_workshop_date__range=( + from_dates, + to_dates), + status='ACCEPTED', requested_workshop_title_id=int(selected_workshoptype), + requested_workshop_coordinator=coordinator.user_id) + + for workshop in proposed_workshops: + workshop_list.append(workshop) + + for workshop in requested_workshops: + workshop_list.append(workshop) + + return render(request, + 'statistics_app/workshop_public_stats.html', + { + "workshoptype_list": workshoptype_list[::-1], + "workshop_list": workshop_list, + "workshoptype_count": workshoptype_count, + "india_map": states}) + + except BaseException: + messages.info(request, 'Please enter Valid Dates') + + return render(request, + 'statistics_app/workshop_public_stats.html', + { + "workshoptype_list": workshoptype_list[::-1], + "workshoptype_count": workshoptype_count, + "india_map": states}) |