diff --git a/stats.py b/stats.py index 192ae9cf894c89eb9a1eaf52227b1bd89b80e1bc..3dc16a22e57e2d938dddcc69490474835365114d 100644 --- a/stats.py +++ b/stats.py @@ -22,3 +22,47 @@ def stats_data(dataname, parameter=None): else: data = query(statsqueries[dataname]) return Response(json.dumps(data, default=date_json_handler), mimetype='application/json') + +@app.route('/stats/viewsperday') +def stats_viewsperday(): + start = None + end = None + courseid = request.args.get('course', None) + lectureid = request.args.get('lecture', None) + videoid = request.args.get('video', None) + print(start, end, courseid, lectureid, videoid) + rows = query('''SELECT log.id AS id, log.time AS time, formats.description AS fmt + FROM log + JOIN videos ON (videos.id = log.obj_id) + JOIN lectures ON (lectures.id = videos.lecture_id) + JOIN courses ON (courses.id = lectures.course_id) + JOIN formats ON (formats.id = videos.video_format) + WHERE (? OR courses.id = ?) AND (? OR lectures.id = ?) AND (? OR videos.id = ?)''', + courseid == None, courseid, lectureid == None, lectureid, videoid == None, videoid) + data = {} + if not end: + end = date.today() + first = None + fmts = ['total'] + for e in rows: + key = e['time'].date() + if not first or key < first: + first = key + if key not in data: + data[key] = {'total': set()} + if e['fmt'] not in data[key]: + data[key][e['fmt']] = set() + data[key]['total'].add(e['id']) + data[key][e['fmt']].add(e['id']) + if e['fmt'] not in fmts: + fmts.append(e['fmt']) + if not start: + start = first + res = {'times': [], 'views': [{'name': name, 'vals': []} for name in fmts]} + while start and start <= end: + res['times'].append(start.isoformat()) + for d in res['views']: + d['vals'].append(len(data.get(start, {}).get(d['name'], set()))) + start += timedelta(days=1) + return Response(json.dumps(res, default=date_json_handler), mimetype='application/json') + diff --git a/templates/base.html b/templates/base.html index 2a630330738881cafa2781661a53df46c15a84c0..69f4c3f38bb8ab556c5eca02674ac51d9f437ec9 100644 --- a/templates/base.html +++ b/templates/base.html @@ -27,6 +27,7 @@ <script src="{{url_for('static', filename='js.cookie.js')}}"></script> {%if ismod() %} <script src="{{url_for('static', filename='moderator.js')}}"></script> + <script src="{{url_for('static', filename='plotly.min.js')}}"></script> {% endif %} <script src="{{url_for('static', filename='videojs/video.js')}}"></script> <script src="{{url_for('static', filename='videojs/ie8/videojs-ie8.js')}}"></script> diff --git a/templates/course.html b/templates/course.html index 27373d2d2792535330c3ac1fdc899033aeb0adc8..20f00cdbb8ae499b64daa5d1d6529b053c752e9f 100644 --- a/templates/course.html +++ b/templates/course.html @@ -4,6 +4,7 @@ {% from 'macros.html' import moderator_checkbox %} {% from 'macros.html' import preview %} {% from 'macros.html' import moderator_permissioneditor %} +{% from 'macros.html' import stats_viewsperday %} {% extends "base.html" %} {% block title %}- {{course.title}}{% endblock %} @@ -46,6 +47,8 @@ </tbody> </table> </div> + <div id="statview" class="col-xs-11" style="height:600px"></div> + {{stats_viewsperday("statview", "Abrufe pro Tag", course=course.id)}} {% endif %} </div> </div> diff --git a/templates/lecture.html b/templates/lecture.html index cfdea4ded41a6aa4a583cde6151d1ef47b2c1b50..b7589bbebe77b235bcddfecc3a29b1cd5d0f57fe 100644 --- a/templates/lecture.html +++ b/templates/lecture.html @@ -5,6 +5,7 @@ {% from 'macros.html' import moderator_editor %} {% from 'macros.html' import moderator_delete %} {% from 'macros.html' import moderator_checkbox %} +{% from 'macros.html' import stats_viewsperday %} {% set page_border = 1 -%} {% extends "base.html" %} @@ -58,6 +59,8 @@ {% endfor %} </table> </div> + <div id="statview" class="col-xs-12" style="height:600px"></div> + {{stats_viewsperday("statview", "Abrufe pro Tag", lecture=lecture.id)}} {% endif %} </div> </div> diff --git a/templates/macros.html b/templates/macros.html index feb47c76115ea16f0406324dbd8f06f45d039dd2..676abdbc5c124a51832096014e51fa6cf9d162e5 100644 --- a/templates/macros.html +++ b/templates/macros.html @@ -245,3 +245,28 @@ $('#embedcodebtn').popover( {% endmacro %} {% macro vtttime(time) %}{{ '%02d:%02d:%02d.000'|format( time//3600, (time//60)%60, time%60) }}{% endmacro %} + +{% macro stats_viewsperday(id, title, type="scatter", course=None, lecture=None, video=None) %} +<script> + $.ajax({ + method: "GET", + url: "{{url_for('stats_viewsperday', course=course, lecture=lecture, video=video)}}", + dataType: "json", + error: moderator.api.handleapierror, + success: function (data) { + var traces = []; + var i = 0; + if (data.views.length == 2) + i = 1; + for (; i < data.views.length; i++) { + traces.push({"x": data.times, "y": data.views[i].vals, "type": "{{type}}", "name": data.views[i].name}); + } + var layout = { + "title": "{{title}}", + "showlegend": (traces.length != 1) + }; + Plotly.newPlot("{{id}}", traces, layout, { "modeBarButtonsToRemove": ['sendDataToCloud','hoverCompareCartesian'], "displaylogo": false}); + } + }); +</script> +{% endmacro %} diff --git a/templates/stats.html b/templates/stats.html index 8c5dcc0c3fe7b7d9726f4c35b7d33bb66108dc72..60ebc4a6f92795b476975e54c96587e38a0e8606 100644 --- a/templates/stats.html +++ b/templates/stats.html @@ -1,4 +1,4 @@ -{% from 'macros.html' import preview %} +{% from 'macros.html' import stats_viewsperday %} {% extends "base.html" %} {% block header %} @@ -60,6 +60,8 @@ } }); </script> + <div id="statview" class="col-xs-12" style="height:600px"></div> + {{stats_viewsperday("statview", "Abrufe pro Tag")}} </div> i </div> </div>