-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Django Imports | ||
from django.contrib import admin | ||
|
||
# Local Imports | ||
from stats.models import TrackLesson | ||
|
||
|
||
admin.site.register(TrackLesson) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class StatsConfig(AppConfig): | ||
name = 'stats' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Django Imports | ||
from django.db import models | ||
from django.utils import timezone | ||
from django.contrib.auth.models import User | ||
|
||
# Local Imports | ||
from yaksh.models import Course, Lesson | ||
|
||
|
||
class TrackLesson(models.Model): | ||
user = models.ForeignKey(User, on_delete=models.CASCADE) | ||
course = models.ForeignKey(Course, on_delete=models.CASCADE) | ||
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE) | ||
current_time = models.CharField(max_length=100, default="00:00:00") | ||
video_duration = models.CharField(max_length=100, default="00:00:00") | ||
last_access_time = models.DateTimeField(default=timezone.now) | ||
creation_time = models.DateTimeField(auto_now_add=True) | ||
|
||
class Meta: | ||
unique_together = ('user', 'course', 'lesson') | ||
|
||
def __str__(self): | ||
return (f"Track {self.lesson} in {self.course} " | ||
f"for {self.user.get_full_name()}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
{% extends "manage.html" %} | ||
|
||
{% block title %} Lesson Views {% endblock %} | ||
{% block script %} | ||
<script type="text/javascript"> | ||
function get_time_in_seconds(time) { | ||
var time = time.split(":"); | ||
var hh = parseInt(time[0]); | ||
var mm = parseInt(time[1]); | ||
var ss = parseInt(time[2]); | ||
return hh * 3600 + mm * 60 + ss; | ||
} | ||
|
||
$(document).ready(function() { | ||
$('#stats-table tr').each(function() { | ||
var td = $(this).find("td"); | ||
var elapsed = td.eq(4).html(); | ||
var duration = td.eq(5).html(); | ||
var input = td.eq(6).find("input"); | ||
if (elapsed != undefined && duration != undefined) { | ||
percent = (get_time_in_seconds(elapsed) / get_time_in_seconds(duration)) * 100; | ||
input.val(Math.round(percent)); | ||
} | ||
}); | ||
}); | ||
</script> | ||
{% endblock %} | ||
{% block content %} | ||
<div class="container"> | ||
{% with objects.object_list as trackings %} | ||
<center> | ||
<h3>Statistics for {% with trackings|first as entry %} {{entry.lesson}} {% endwith %}</h3> | ||
</center> | ||
<a class="btn btn-primary" href="{% url 'yaksh:lesson_statistics' course_id lesson_id %}"> | ||
<i class="fa fa-arrow-left"></i> Back | ||
</a> | ||
<br><br> | ||
{% include "yaksh/paginator.html" %} | ||
<br> | ||
<h4><strong>{{total}} student(s) viewed this lesson</strong></h4> | ||
<table class="table table-responsive" id="stats-table"> | ||
<tr> | ||
<th>Sr No.</th> | ||
<th>Student Name</th> | ||
<th>Last access on</th> | ||
<th>Started on</th> | ||
<th>Current Time</th> | ||
<th>Video Duration</th> | ||
<th>Percentage watched</th> | ||
</tr> | ||
{% for track in trackings %} | ||
<tr> | ||
<td>{{ forloop.counter0|add:objects.start_index }}</td> | ||
<td>{{track.user.get_full_name}}</td> | ||
<td>{{track.last_access_time}}</td> | ||
<td>{{track.creation_time}}</td> | ||
<td>{{track.current_time}}</td> | ||
<td>{{track.video_duration}}</td> | ||
<td> | ||
<input type="text" class="form-control" readonly=""> | ||
</td> | ||
</tr> | ||
{% endfor %} | ||
</table> | ||
{% endwith %} | ||
<br> | ||
{% include "yaksh/paginator.html" %} | ||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from django.test import TestCase | ||
|
||
# Create your tests here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from django.urls import path | ||
from stats import views | ||
|
||
|
||
app_name = "stats" | ||
|
||
urlpatterns = [ | ||
path('submit/video/watch/<int:tracker_id>', | ||
views.add_tracker, name='add_tracker'), | ||
path('view/watch/stats/<int:course_id>/<int:lesson_id>', | ||
views.view_lesson_watch_stats, name='view_lesson_watch_stats'), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Django Imports | ||
from django.shortcuts import render, get_object_or_404 | ||
from django.http import JsonResponse | ||
from django.utils import timezone | ||
from django.contrib.auth.decorators import login_required | ||
from django.core.paginator import Paginator | ||
|
||
# Local Imports | ||
from stats.models import TrackLesson | ||
from yaksh.models import Course | ||
from yaksh.decorators import email_verified | ||
|
||
|
||
@login_required | ||
@email_verified | ||
def add_tracker(request, tracker_id): | ||
user = request.user | ||
track = get_object_or_404( | ||
TrackLesson.objects.select_related("course"), id=tracker_id | ||
) | ||
if not track.course.is_student(user): | ||
raise Http404("You are not enrolled in this course") | ||
context = {} | ||
video_duration = request.POST.get('video_duration') | ||
current_time = request.POST.get('current_video_time') | ||
if current_time: | ||
track.current_time = current_time | ||
track.video_duration = video_duration | ||
track.last_access_time = timezone.now() | ||
track.save() | ||
success = True | ||
else: | ||
success = False | ||
context = {"success": success} | ||
return JsonResponse(context) | ||
|
||
|
||
@login_required | ||
@email_verified | ||
def view_lesson_watch_stats(request, course_id, lesson_id): | ||
user = request.user | ||
course = get_object_or_404(Course, pk=course_id) | ||
if not course.is_creator(user) and not course.is_teacher(user): | ||
raise Http404('This course does not belong to you') | ||
trackings = TrackLesson.objects.get_queryset().filter( | ||
course_id=course_id, lesson_id=lesson_id | ||
).order_by("id") | ||
total = trackings.count() | ||
paginator = Paginator(trackings, 30) | ||
page = request.GET.get('page') | ||
trackings = paginator.get_page(page) | ||
context = {'objects': trackings, 'total': total, 'course_id': course_id, | ||
'lesson_id': lesson_id} | ||
return render(request, 'view_lesson_tracking.html', context) |