Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
2
2020-101
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Sachith Fernando
2020-101
Commits
bcb44959
Commit
bcb44959
authored
Jan 06, 2021
by
SohanDanushka
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/QA_RELEASE' into db_and_monitoring_IT17097284
parents
a22f93b0
28bdfdce
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
959 additions
and
249 deletions
+959
-249
FirstApp/api.py
FirstApp/api.py
+85
-3
FirstApp/logic/batch_process.py
FirstApp/logic/batch_process.py
+51
-8
FirstApp/serializers.py
FirstApp/serializers.py
+6
-1
FirstApp/templates/FirstApp/Home.html
FirstApp/templates/FirstApp/Home.html
+1
-1
FirstApp/templates/FirstApp/activity.html
FirstApp/templates/FirstApp/activity.html
+265
-62
FirstApp/templates/FirstApp/emotion.html
FirstApp/templates/FirstApp/emotion.html
+281
-124
FirstApp/templates/FirstApp/gaze.html
FirstApp/templates/FirstApp/gaze.html
+172
-48
FirstApp/templates/FirstApp/template.html
FirstApp/templates/FirstApp/template.html
+1
-0
FirstApp/urls.py
FirstApp/urls.py
+3
-0
LectureSummarizingApp/Voice Recorder.py
LectureSummarizingApp/Voice Recorder.py
+26
-0
LectureSummarizingApp/models.py
LectureSummarizingApp/models.py
+1
-0
LectureSummarizingApp/templates/LectureSummarizingApp/RecordLecture.html
...ingApp/templates/LectureSummarizingApp/RecordLecture.html
+54
-0
LectureSummarizingApp/urls.py
LectureSummarizingApp/urls.py
+1
-0
LectureSummarizingApp/views.py
LectureSummarizingApp/views.py
+10
-1
integrated_slpes/urls.py
integrated_slpes/urls.py
+2
-1
No files found.
FirstApp/api.py
View file @
bcb44959
...
@@ -168,13 +168,17 @@ class LectureVideoViewSet(APIView):
...
@@ -168,13 +168,17 @@ class LectureVideoViewSet(APIView):
# serializer = LectureVideoSerializer(data=request.data, many=True)
# serializer = LectureVideoSerializer(data=request.data, many=True)
serializer
=
LectureVideoSerializer
(
data
=
request
.
data
)
serializer
=
LectureVideoSerializer
(
data
=
request
.
data
)
# serializer.create(validated_data=request.data)
# serializer.create(validated_data=request.data)
data
=
{}
data_ser
=
{}
if
serializer
.
is_valid
(
raise_exception
=
ValueError
):
if
serializer
.
is_valid
(
raise_exception
=
ValueError
):
print
(
'valid'
)
data
=
serializer
.
create
(
validated_data
=
request
.
data
)
serializer
.
create
(
validated_data
=
request
.
data
)
print
(
'data: '
,
data
)
# data_ser = LectureVideoSerializer(data, many=True)
return
Response
(
serializer
.
data
,
status
=
status
.
HTTP_201_CREATED
)
# return Response(serializer.data, status=status.HTTP_201_CREATED)
return
Response
(
data
,
status
=
status
.
HTTP_201_CREATED
)
# return Response(serializer.error_messages,
# return Response(serializer.error_messages,
...
@@ -462,6 +466,7 @@ class GetLectureEmotionReportViewSet(APIView):
...
@@ -462,6 +466,7 @@ class GetLectureEmotionReportViewSet(APIView):
lecture_emotions
=
LectureEmotionReport
.
objects
.
filter
(
lecture_video_id__lecture_video_id
=
lecture_video_id
)
lecture_emotions
=
LectureEmotionReport
.
objects
.
filter
(
lecture_video_id__lecture_video_id
=
lecture_video_id
)
serializer
=
LectureEmotionSerializer
(
lecture_emotions
,
many
=
True
)
serializer
=
LectureEmotionSerializer
(
lecture_emotions
,
many
=
True
)
print
(
'data: '
,
serializer
.
data
)
return
Response
({
return
Response
({
"response"
:
serializer
.
data
,
"response"
:
serializer
.
data
,
...
@@ -1565,3 +1570,80 @@ class TestRandom(APIView):
...
@@ -1565,3 +1570,80 @@ class TestRandom(APIView):
"response"
:
random
"response"
:
random
})
})
# this API will display the upcoming lectures for the lecturer (temporary API)
class
DisplayUpcomingLecturesAPI
(
APIView
):
def
get
(
self
,
request
):
lecturer
=
request
.
query_params
.
get
(
'lecturer'
)
lecturer
=
int
(
lecturer
)
cur_date
=
datetime
.
datetime
.
now
()
.
date
()
cur_time
=
datetime
.
datetime
.
now
()
.
time
()
eligible_start_time
=
''
eligible_end_time
=
''
subject_id
=
0
subject_name
=
''
subject_code
=
''
# retrieve the faculty timetable
faculty_timetable
=
FacultyTimetable
.
objects
.
all
()
# serialize the timetable
faculty_timetable_serialized
=
FacultyTimetableSerializer
(
faculty_timetable
,
many
=
True
)
# get the serialized timetable data
faculty_timetable_serialized_data
=
faculty_timetable_serialized
.
data
# iterate through the serialized timetable data
for
timetable
in
faculty_timetable_serialized_data
:
# get the 'timetable' field
daily_timetable
=
timetable
[
'timetable'
]
# iterate through the 'timetable' field
for
day_timetable
in
daily_timetable
:
# get the 'time_slots' field for a given day
time_slots
=
day_timetable
[
'time_slots'
]
# iterate through the time slots
for
time_slot
in
time_slots
:
# if the lecturer is the currently logged in lecturer
if
lecturer
==
time_slot
[
'lecturer'
][
'id'
]:
# find the upcoming lecture for the logged-in lecturer
if
cur_date
==
day_timetable
[
'date'
]:
# get the start and end times
start_time
=
time_slot
[
'start_time'
]
end_time
=
time_slot
[
'end_time'
]
start_time_list
=
str
(
start_time
)
.
split
(
":"
)
start_time_date
=
datetime
.
datetime
.
now
()
.
replace
(
hour
=
int
(
start_time_list
[
0
]),
minute
=
int
(
start_time_list
[
1
]),
second
=
int
(
start_time_list
[
2
]))
end_time_list
=
str
(
end_time
)
.
split
(
":"
)
end_time_date
=
datetime
.
datetime
.
now
()
.
replace
(
hour
=
int
(
end_time_list
[
0
]),
minute
=
int
(
end_time_list
[
1
]),
second
=
int
(
end_time_list
[
2
]))
# check for the upcoming time slot
if
(
start_time_date
.
time
()
>
cur_time
):
eligible_start_time
=
start_time_date
.
time
()
eligible_end_time
=
end_time_date
.
time
()
subject_id
=
time_slot
[
'subject'
][
'id'
]
subject_name
=
time_slot
[
'subject'
][
'name'
]
subject_code
=
time_slot
[
'subject'
][
'subject_code'
]
return
Response
({
"start_time"
:
eligible_start_time
,
"end_time"
:
eligible_end_time
,
"subject_id"
:
subject_id
,
"subject_name"
:
subject_name
,
"subject_code"
:
subject_code
,
})
FirstApp/logic/batch_process.py
View file @
bcb44959
import
requests
import
requests
import
json
def
batch_process
(
video_id
,
video_name
):
def
student_behavior_
batch_process
(
video_id
,
video_name
):
is_all_processed
=
False
# call the activity process
# call the activity process
activity_resp
=
requests
.
get
(
'http://127.0.0.1:8000/process-lecture-activity/?lecture_video_name='
+
video_name
+
'&lecture_video_id='
+
video_id
)
activity_resp
=
requests
.
get
(
'http://127.0.0.1:8000/process-lecture-activity/'
,
params
=
{
'lecture_video_name'
:
video_name
,
'lecture_video_id'
:
video_id
})
# if the activity process is success
if
activity_resp
.
json
()[
'response'
]:
# call the emotion process
emotion_resp
=
requests
.
get
(
'http://127.0.0.1:8000/process-lecture-emotion/?lecture_video_name='
,
params
=
{
'lecture_video_name'
:
video_name
,
'lecture_video_id'
:
video_id
})
# call the emotion pro
cess
# if the emotion process is suc
cess
emotion_resp
=
requests
.
get
(
'http://127.0.0.1:8000/process-lecture-emotion/?lecture_video_name='
+
video_name
+
'&lecture_video_id='
+
video_id
)
if
emotion_resp
.
json
()[
'response'
]:
# call the gaze process
# call the gaze process
gaze_resp
=
requests
.
get
(
'http://127.0.0.1:8000/process-lecture-gaze-estimation/?lecture_video_name='
+
video_name
+
'&lecture_video_id='
+
video_id
)
gaze_resp
=
requests
.
get
(
'http://127.0.0.1:8000/process-lecture-gaze-estimation/?lecture_video_name='
,
params
=
{
'lecture_video_name'
:
video_name
,
'lecture_video_id'
:
video_id
}
)
# if the gaze estimation process is successful
if
gaze_resp
.
json
()[
'response'
]:
is_all_processed
=
True
pass
return
is_all_processed
# this method will save the lecture video
# this method will save the lecture video
def
save_student_lecture_video
(
student_video
):
def
save_student_lecture_video
(
student_video
):
data_dumps
=
json
.
dumps
(
student_video
)
headers
=
{
'Content-Type'
:
'application/json'
}
# call the API
# call the API
student_video_save_resp
=
requests
.
post
(
'http://127.0.0.1:8000/lecture-video'
,
student_video
)
# student_video_save_resp = requests.post('http://127.0.0.1:8000/lecture-video', student_video)
\ No newline at end of file
student_video_save_resp
=
requests
.
post
(
url
=
'http://127.0.0.1:8000/lecture-video'
,
data
=
data_dumps
,
headers
=
headers
)
data
=
student_video_save_resp
.
json
()
return
data
[
0
]
if
__name__
==
'__main__'
:
# content = {
# "lecturer": 1,
# "subject": 16,
# "date": "2020-12-09",
# "video_name": "Video_test_19.mp4",
# "video_length": "00:45:06"
# }
#
#
# data_dumps = json.dumps(content)
# data_json = json.loads(data_dumps)
#
#
# save_student_lecture_video(content)
student_behavior_batch_process
(
8
,
"Video_test_8.mp4"
)
FirstApp/serializers.py
View file @
bcb44959
...
@@ -275,6 +275,11 @@ class LectureVideoSerializer(serializers.ModelSerializer):
...
@@ -275,6 +275,11 @@ class LectureVideoSerializer(serializers.ModelSerializer):
video_length
=
video_length
video_length
=
video_length
)
)
# retrieve the created object
created_lecture_video
=
LectureVideo
.
objects
.
filter
(
lecture_video_id
=
lecture_video
)
create_lecture_video_ser
=
LectureVideoSerializer
(
created_lecture_video
,
many
=
True
)
create_lecture_video_ser_data
=
create_lecture_video_ser
.
data
# faculty_data = validated_data.pop('faculty')
# faculty_data = validated_data.pop('faculty')
# serialized_faculty = FacultySerializer(data=faculty_data)
# serialized_faculty = FacultySerializer(data=faculty_data)
#
#
...
@@ -294,7 +299,7 @@ class LectureVideoSerializer(serializers.ModelSerializer):
...
@@ -294,7 +299,7 @@ class LectureVideoSerializer(serializers.ModelSerializer):
#
#
# return lecturer
# return lecturer
#
#
return
lecture_video
return
create_lecture_video_ser_data
return
None
return
None
...
...
FirstApp/templates/FirstApp/Home.html
View file @
bcb44959
...
@@ -2687,7 +2687,7 @@
...
@@ -2687,7 +2687,7 @@
</button>
</button>
</div>
</div>
<div
class=
"modal-body text-center"
>
<div
class=
"modal-body text-center"
>
<h3
class=
"font-weight-bold"
>
Student Activity vs. Student
Emotions
</h3>
<h3
class=
"font-weight-bold"
>
Student Activity vs. Student
Gaze
</h3>
<!-- ajax loader -->
<!-- ajax loader -->
<div
class=
"text-center"
id=
"student_activity_gaze_corr_loader"
hidden
>
<div
class=
"text-center"
id=
"student_activity_gaze_corr_loader"
hidden
>
...
...
FirstApp/templates/FirstApp/activity.html
View file @
bcb44959
...
@@ -21,6 +21,11 @@
...
@@ -21,6 +21,11 @@
<!-- Core plugin JavaScript-->
<!-- Core plugin JavaScript-->
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<!-- canvasJS implementation -->
<script
src=
"https://canvasjs.com/assets/script/canvasjs.min.js"
></script>
<script
type=
"text/javascript"
>
<script
type=
"text/javascript"
>
...
@@ -32,12 +37,21 @@
...
@@ -32,12 +37,21 @@
var
global_lecture_date
=
''
;
var
global_lecture_date
=
''
;
var
global_lecturer_video_name
=
''
;
var
global_lecturer_video_name
=
''
;
var
lecturer_fps
=
0
;
var
lecturer_fps
=
0
;
var
lecture_activity_frame_group_percentages
=
{};
var
lecture_video_time_landmarks
=
[];
var
CHART
=
''
;
;
//jquery
//jquery
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
//disable the 'integrate_activity' button
$
(
'
#integrate_activity
'
).
hide
();
//hide the 'Generate Report' button
{
#
$
(
'
#generate_report_before
'
).
hide
();
#
}
$
(
'
#generate_report
'
).
hide
();
//select a particular subject
//select a particular subject
$
(
'
input[type=radio]
'
).
click
(
function
()
{
$
(
'
input[type=radio]
'
).
click
(
function
()
{
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
...
@@ -76,6 +90,7 @@
...
@@ -76,6 +90,7 @@
let
real_class
=
clicked_class
.
split
(
'
'
)[
1
];
let
real_class
=
clicked_class
.
split
(
'
'
)[
1
];
real_class
=
'
.
'
+
real_class
;
real_class
=
'
.
'
+
real_class
;
let
date
=
e
.
target
.
parentNode
.
parentNode
.
firstChild
.
innerHTML
;
let
date
=
e
.
target
.
parentNode
.
parentNode
.
firstChild
.
innerHTML
;
//assign the date
//assign the date
global_lecture_date
=
date
;
global_lecture_date
=
date
;
...
@@ -161,6 +176,9 @@
...
@@ -161,6 +176,9 @@
$
(
'
#generate_report_before
'
).
attr
(
'
disabled
'
,
false
);
$
(
'
#generate_report_before
'
).
attr
(
'
disabled
'
,
false
);
$
(
'
#video_modal
'
).
modal
();
$
(
'
#video_modal
'
).
modal
();
//display the 'integrate activity' button
$
(
'
#integrate_activity
'
).
show
();
}
}
//binding a click event for 'btn-primary' buttons
//binding a click event for 'btn-primary' buttons
...
@@ -254,16 +272,15 @@
...
@@ -254,16 +272,15 @@
//fetch the lecture recorded video name
//fetch the lecture recorded video name
fetch
(
'
http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=
'
+
global_lecturer
+
'
&subject=
'
+
global_subject
+
'
&date=
'
+
global_lecture_date
)
fetch
(
'
http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=
'
+
global_lecturer
+
'
&subject=
'
+
global_subject
+
'
&date=
'
+
global_lecture_date
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_3.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_3.mp4
"
;
#
}
//fetch data from the API
//fetch data from the API
fetch
(
'
http://127.0.0.1:8000/get-lecture-activity-for-frame?video_name=
'
+
global_video_name
)
fetch
(
'
http://127.0.0.1:8000/get-lecture-activity-for-frame?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
res
)
=>
res
.
json
())
...
@@ -524,6 +541,189 @@
...
@@ -524,6 +541,189 @@
});
});
//this function will handle the activity 'summary' button
$
(
'
#graph-tab
'
).
click
(
function
(
e
)
{
//display the graph loader
$
(
'
#graph_loader
'
).
attr
(
'
hidden
'
,
false
);
//fetch the video time landmark details
fetch
(
'
http://127.0.0.1:8000/get-lecture-video-summary-time-landmarks/?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignTimeLandmarks
(
out
.
response
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
//change the innerHTML of the clicked button
{
#
e
.
target
.
innerHTML
=
"
<span class='font-italic'>Processing</span>
"
;
#
}
let
phone_perct
=
$
(
'
#phone_perct
'
).
text
().
split
(
"
%
"
)[
0
];
let
listen_perct
=
$
(
'
#listening_perct
'
).
text
().
split
(
"
%
"
)[
0
];
let
note_perct
=
$
(
'
#writing_perct
'
).
text
().
split
(
"
%
"
)[
0
];
//fetch the activity summary details
fetch
(
'
http://127.0.0.1:8000/get-lecture-activity-summary/?video_name=
'
+
global_video_name
+
'
&phone_perct=
'
+
phone_perct
+
'
¬e_perct=
'
+
note_perct
+
'
&listen_perct=
'
+
listen_perct
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
activityFrameGroupPercentages
(
out
,
e
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
});
//this function will assign lecture video time landmarks
function
assignTimeLandmarks
(
response
)
{
lecture_video_time_landmarks
=
response
;
}
//this function will handle the retrieved activity frame group percentages
function
activityFrameGroupPercentages
(
response
,
e
)
{
lecture_activity_frame_group_percentages
=
response
.
frame_group_percentages
;
let
frame_landmarks
=
response
.
frame_landmarks
;
{
#
let
frame_group_dict
=
response
.
frame_group_dict
;
#
}
let
activity_labels
=
response
.
activity_labels
;
let
comment_list
=
response
.
comments
;
//render the chart onto the modal body
renderActivityChart
(
activity_labels
);
}
//this function will call the activity chart function
function
renderActivityChart
(
activity_labels
)
{
//hide the graph loader
$
(
'
#graph_loader
'
).
hide
();
//get the activity label length
let
activity_label_length
=
activity_labels
.
length
;
let
data
=
[];
//loop through the activity labels
for
(
let
k
=
0
;
k
<
activity_label_length
;
k
++
)
{
let
label
=
activity_labels
[
k
];
let
datapoints
=
[];
let
count
=
0
;
//loop through the activity frame groups
for
(
let
key
in
lecture_activity_frame_group_percentages
)
{
let
frame_group_details
=
lecture_activity_frame_group_percentages
[
key
];
let
activity_perct
=
frame_group_details
[
label
];
let
point
=
{
label
:
lecture_video_time_landmarks
[
count
],
y
:
activity_perct
};
datapoints
.
push
(
point
);
count
++
;
}
let
obj
=
{
type
:
"
line
"
,
showInLegend
:
true
,
name
:
label
,
markerType
:
"
square
"
,
{
#
xValueFormatString
:
"
DD MMM, YYYY
"
,
#
}
xValueFormatString
:
"
hh:mm:ss
"
,
color
:
getRandomColor
(),
dataPoints
:
datapoints
};
data
.
push
(
obj
);
}
CHART
=
new
CanvasJS
.
Chart
(
"
ActivityChartContainer
"
,
{
animationEnabled
:
true
,
theme
:
"
light2
"
,
title
:
{
text
:
"
Student Activity Behavior
"
},
axisX
:
{
title
:
"
Duration
"
,
{
#
valueFormatString
:
"
DD MMM
"
,
#
}
valueFormatString
:
"
hh:mm:ss
"
,
crosshair
:
{
enabled
:
true
,
snapToDataPoint
:
true
}
},
axisY
:
{
title
:
"
Percentage
"
,
includeZero
:
true
,
crosshair
:
{
enabled
:
true
}
},
toolTip
:
{
shared
:
true
},
legend
:
{
cursor
:
"
pointer
"
,
verticalAlign
:
"
top
"
,
horizontalAlign
:
"
right
"
,
dockInsidePlotArea
:
true
,
itemclick
:
toogleDataSeries
},
data
:
data
});
{
#
chart
.
render
();
#
}
CHART
.
render
();
//show the 'generate report' button
$
(
'
#generate_report
'
).
show
();
}
//this function will generate random colors
function
getRandomColor
()
{
var
letters
=
'
0123456789ABCDEF
'
;
var
color
=
'
#
'
;
for
(
var
i
=
0
;
i
<
6
;
i
++
)
{
color
+=
letters
[
Math
.
floor
(
Math
.
random
()
*
16
)];
}
return
color
;
}
//this function will toggle the content
function
toogleDataSeries
(
e
)
{
if
(
typeof
(
e
.
dataSeries
.
visible
)
===
"
undefined
"
||
e
.
dataSeries
.
visible
)
{
e
.
dataSeries
.
visible
=
false
;
}
else
{
e
.
dataSeries
.
visible
=
true
;
}
chart
.
render
();
}
//this method will handle the 'Generate Report' button
$
(
'
#generate_report
'
).
click
(
function
()
{
let
script
=
"
<script src='https://canvasjs.com/assets/script/canvasjs.min.js'><
\
/script>
"
;
CHART
.
print
();
{
#
var
prtContent
=
document
.
getElementById
(
"
ActivityChartContainer
"
);
#
}
{
#
var
WinPrint
=
window
.
open
(
''
,
''
,
'
left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0
'
);
#
}
{
#
var
WinPrint
=
window
.
open
(
''
);
#
}
{
#
WinPrint
.
document
.
write
(
prtContent
.
innerHTML
);
#
}
{
#
WinPrint
.
document
.
write
(
script
);
#
}
{
#
WinPrint
.
document
.
write
(
'
<h1>This is Ishan</h1>
'
);
#
}
{
#
WinPrint
.
document
.
close
();
#
}
{
#
WinPrint
.
focus
();
#
}
{
#
WinPrint
.
print
();
#
}
{
#
WinPrint
.
close
();
#
}
});
});
});
</script>
</script>
...
@@ -548,8 +748,12 @@
...
@@ -548,8 +748,12 @@
<!-- Page Heading -->
<!-- Page Heading -->
<div
class=
"d-sm-flex align-items-center justify-content-between mb-4"
>
<div
class=
"d-sm-flex align-items-center justify-content-between mb-4"
>
<h1
class=
"h3 mb-0 text-gray-800"
>
Student Activity Recognition
</h1>
<h1
class=
"h3 mb-0 text-gray-800"
>
Student Activity Recognition
</h1>
{#
<button
type=
"button"
data-target=
"#generateReportModal"
data-toggle=
"modal"
class=
"d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"
id=
"generate_report_before"
disabled
><i
#
}
<button
type=
"button"
class=
"btn btn-primary"
id=
"generate_report"
>
Generate Report
</button>
{
#
class=
"fas fa-download fa-sm text-white-50"
></i>
Generate Report
</button>
#}
{#
<button
type=
"button"
#
}
{
#
class=
"d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm"
#
}
{
#
id=
"generate_report_before"
><i
#
}
{
#
class=
"fas fa-download fa-sm text-white-50"
></i>
Generate Report#}
{#
</button>
#}
</div>
</div>
...
@@ -702,18 +906,18 @@
...
@@ -702,18 +906,18 @@
<!--this area will display the progress bars -->
<!--this area will display the progress bars -->
<div
class=
"progress_area mt-4"
hidden
>
<div
class=
"progress_area mt-4"
hidden
>
<!--talking with friends -->
<!--talking with friends -->
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"1"
{#
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"1"
#
}
data-label=
"talking-with-friends"
>
{
#
data-label=
"talking-with-friends"
>
#}
<h4
class=
"small font-weight-bold"
>
Talking with friends
</h4>
{#
<h4
class=
"small font-weight-bold"
>
Talking with friends
</h4>
#}
</a>
{#
</a>
#}
<span
class=
"float-right"
id=
"talking_perct"
>
40%
</span>
{#
<span
class=
"float-right"
id=
"talking_perct"
>
40%
</span>
#}
<div
class=
"progress mb-4"
>
{#
<div
class=
"progress mb-4"
>
#}
<div
class=
"progress-bar bg-danger"
role=
"progressbar"
{#
<div
class=
"progress-bar bg-danger"
role=
"progressbar"
#
}
id=
"talking_width"
{
#
id=
"talking_width"
#
}
style=
"width: 20%"
{
#
style=
"width: 20%"
#
}
aria-valuenow=
"20"
aria-valuemin=
"0"
{
#
aria-valuenow=
"20"
aria-valuemin=
"0"
#
}
aria-valuemax=
"100"
></div>
{
#
aria-valuemax=
"100"
></div>
#}
</div>
{#
</div>
#}
<!--phone checking -->
<!--phone checking -->
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"0"
<a
href=
"#"
class=
"btn btn-link labels"
data-number=
"0"
...
@@ -765,45 +969,44 @@
...
@@ -765,45 +969,44 @@
<!--graph tab -->
<!--graph tab -->
<div
class=
"tab-pane fade"
id=
"graph"
role=
"tabpanel"
<div
class=
"tab-pane fade"
id=
"graph"
role=
"tabpanel"
aria-labelledby=
"profile-tab"
>
aria-labelledby=
"profile-tab"
>
<!-- graph loader -->
<div
class=
"text-center mt-3"
id=
"graph_loader"
hidden
>
<img
src=
"{% static 'FirstApp/images/ajax-loader.gif' %}"
alt=
"Loader"
>
</div>
<!-- end of graph loader -->
<!--card content -->
<!--card content -->
<div
class=
"card shadow mb-4 p-3"
>
<div
class=
"card shadow mb-4 p-3"
>
<!-- Card Header - Dropdown -->
{#
<!-- Card Header - Dropdown -->
#}
<div
class=
"card-header py-3 d-flex flex-row align-items-center justify-content-between"
>
{#
<div
class=
"card-header py-3 d-flex flex-row align-items-center justify-content-between"
>
#}
<h6
class=
"m-0 font-weight-bold text-primary"
>
Student
{#
<h6
class=
"m-0 font-weight-bold text-primary"
>
Student#}
Activities
</h6>
{# Activities
</h6>
#}
<div
class=
"dropdown no-arrow"
>
{#
<div
class=
"dropdown no-arrow"
>
#}
<a
class=
"dropdown-toggle"
href=
"#"
role=
"button"
{#
<a
class=
"dropdown-toggle"
href=
"#"
role=
"button"
#
}
id=
"dropdownMenuLink"
data-toggle=
"dropdown"
{
#
id=
"dropdownMenuLink"
data-toggle=
"dropdown"
#
}
aria-haspopup=
"true"
aria-expanded=
"false"
>
{
#
aria-haspopup=
"true"
aria-expanded=
"false"
>
#}
<i
class=
"fas fa-ellipsis-v fa-sm fa-fw text-gray-400"
></i>
{#
<i
class=
"fas fa-ellipsis-v fa-sm fa-fw text-gray-400"
></i>
#}
</a>
{#
</a>
#}
<div
class=
"dropdown-menu dropdown-menu-right shadow animated--fade-in"
{#
<div
class=
"dropdown-menu dropdown-menu-right shadow animated--fade-in"
#
}
aria-labelledby=
"dropdownMenuLink"
>
{
#
aria-labelledby=
"dropdownMenuLink"
>
#}
<div
class=
"dropdown-header"
>
Dropdown Header:
</div>
{#
<div
class=
"dropdown-header"
>
Dropdown Header:
</div>
#}
<a
class=
"dropdown-item"
href=
"#"
>
Action
</a>
{#
<a
class=
"dropdown-item"
href=
"#"
>
Action
</a>
#}
<a
class=
"dropdown-item"
href=
"#"
>
Another action
</a>
{#
<a
class=
"dropdown-item"
href=
"#"
>
Another action
</a>
#}
<div
class=
"dropdown-divider"
></div>
{#
<div
class=
"dropdown-divider"
></div>
#}
<a
class=
"dropdown-item"
href=
"#"
>
Something else here
</a>
{#
<a
class=
"dropdown-item"
href=
"#"
>
Something else here
</a>
#}
</div>
{#
</div>
#}
</div>
{#
</div>
#}
</div>
{#
</div>
#}
<!-- Card Body -->
<!-- Card Body -->
<div
class=
"card-body"
>
<div
class=
"card-body"
>
<div
class=
"chart-pie pt-4 pb-2"
>
<div
id=
"ActivityChartContainer"
<canvas
id=
"myPieChart"
></canvas>
style=
"height: 370px; max-width: 920px; margin: 0px auto;"
></div>
</div>
<div
class=
"mt-4 text-center small"
>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-primary"
></i>
Direct
</span>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-success"
></i>
Social
</span>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-info"
></i>
Referral
</span>
</div>
</div>
</div>
<!-- End of Card Body -->
</div>
</div>
</div>
</div>
...
@@ -1084,11 +1287,11 @@
...
@@ -1084,11 +1287,11 @@
type=
"video/mp4"
>
type=
"video/mp4"
>
Your browser does not support the video tag.
Your browser does not support the video tag.
</video>
</video>
{#
<video
width=
"500"
height=
"300"
id=
"student_video"
controls
>
#}
{#
<video
width=
"500"
height=
"300"
id=
"student_video"
controls
>
#}
{#
<source
src=
"{% static 'FirstApp/videos/Video_test_2.mp4' %}"
#
}
{#
<source
src=
"{% static 'FirstApp/videos/Video_test_2.mp4' %}"
#
}
{
#
type=
"video/mp4"
>
#}
{
#
type=
"video/mp4"
>
#}
{# Your browser does not support the video tag.#}
{# Your browser does not support the video tag.#}
{#
</video>
#}
{#
</video>
#}
</div>
</div>
<!--end of student video section -->
<!--end of student video section -->
...
@@ -1155,10 +1358,10 @@
...
@@ -1155,10 +1358,10 @@
<!--display lecture video -->
<!--display lecture video -->
<div
class=
"text-center m-3"
id=
"lecturer_video_section"
>
<div
class=
"text-center m-3"
id=
"lecturer_video_section"
>
{#
<!--temporary text -->
#}
{#
<!--temporary text -->
#}
{#
<div
class=
"text-center"
id=
"temp_lecturer_text"
>
#}
{#
<div
class=
"text-center"
id=
"temp_lecturer_text"
>
#}
{#
<span
class=
"font-italic"
>
No video was found
</span>
#}
{#
<span
class=
"font-italic"
>
No video was found
</span>
#}
{#
</div>
#}
{#
</div>
#}
<!--display lecturer video -->
<!--display lecturer video -->
...
...
FirstApp/templates/FirstApp/emotion.html
View file @
bcb44959
...
@@ -21,6 +21,9 @@
...
@@ -21,6 +21,9 @@
<!-- Core plugin JavaScript-->
<!-- Core plugin JavaScript-->
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<!-- canvasJS implementation -->
<script
src=
"https://canvasjs.com/assets/script/canvasjs.min.js"
></script>
<script
type=
"text/javascript"
>
<script
type=
"text/javascript"
>
...
@@ -31,10 +34,16 @@
...
@@ -31,10 +34,16 @@
var
global_lecturer_subject_index
=
0
;
var
global_lecturer_subject_index
=
0
;
var
global_lecturer_video_name
=
''
;
var
global_lecturer_video_name
=
''
;
var
lecturer_fps
=
0
;
var
lecturer_fps
=
0
;
var
lecture_emotion_frame_group_percentages
=
{};
var
lecture_video_time_landmarks
=
[];
//jquery
//jquery
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
//hide the 'integrate emotion' button
$
(
'
#integrate_emotion
'
).
hide
();
//select a particular subject
//select a particular subject
$
(
'
input[type=radio]
'
).
click
(
function
()
{
$
(
'
input[type=radio]
'
).
click
(
function
()
{
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
...
@@ -145,8 +154,8 @@
...
@@ -145,8 +154,8 @@
$
(
'
#video_name
'
).
text
(
video
.
video_name
);
$
(
'
#video_name
'
).
text
(
video
.
video_name
);
$
(
'
#video_duration
'
).
text
(
video
.
video_length
);
$
(
'
#video_duration
'
).
text
(
video
.
video_length
);
$
(
'
#video_date
'
).
text
(
video
.
date
);
$
(
'
#video_date
'
).
text
(
video
.
date
);
{
#
global_lecture_video_id
=
video
.
lecture_video_id
;
#
}
global_lecture_video_id
=
video
.
lecture_video_id
;
global_lecture_video_id
=
video
.
id
;
{
#
global_lecture_video_id
=
video
.
id
;
#
}
global_video_name
=
video
.
video_name
;
global_video_name
=
video
.
video_name
;
...
@@ -157,6 +166,9 @@
...
@@ -157,6 +166,9 @@
}
}
$
(
'
#video_modal
'
).
modal
();
$
(
'
#video_modal
'
).
modal
();
//display the 'integrate emotion' button
$
(
'
#integrate_emotion
'
).
show
();
}
}
//binding a click event for 'btn-primary' buttons
//binding a click event for 'btn-primary' buttons
...
@@ -255,9 +267,9 @@
...
@@ -255,9 +267,9 @@
//fetch the lecture recorded video name
//fetch the lecture recorded video name
fetch
(
'
http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=
'
+
global_lecturer
+
'
&subject=
'
+
global_subject
+
'
&date=
'
+
global_lecture_date
)
fetch
(
'
http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=
'
+
global_lecturer
+
'
&subject=
'
+
global_subject
+
'
&date=
'
+
global_lecture_date
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
...
@@ -537,6 +549,151 @@
...
@@ -537,6 +549,151 @@
});
});
//this function will handle the activity 'summary' button
$
(
'
#graph-tab
'
).
click
(
function
(
e
)
{
//display the graph loader
$
(
'
#graph_loader
'
).
attr
(
'
hidden
'
,
false
);
//fetch the video time landmark details
fetch
(
'
http://127.0.0.1:8000/get-lecture-video-summary-time-landmarks/?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignTimeLandmarks
(
out
.
response
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
//fetch the activity summary details
fetch
(
'
http://127.0.0.1:8000/get-lecture-emotion-summary/?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
emotionFrameGroupPercentages
(
out
,
e
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
});
//this function will assign lecture video time landmarks
function
assignTimeLandmarks
(
response
)
{
lecture_video_time_landmarks
=
response
;
}
//this function will handle the retrieved emotion frame group percentages
function
emotionFrameGroupPercentages
(
response
,
e
)
{
lecture_emotion_frame_group_percentages
=
response
.
frame_group_percentages
;
let
frame_landmarks
=
response
.
frame_landmarks
;
let
emotion_labels
=
response
.
emotion_labels
;
//render the chart onto the modal body
renderEmotionChart
(
emotion_labels
);
}
//this function will call the emotion chart function
function
renderEmotionChart
(
emotion_labels
)
{
//get the activity label length
let
emotion_label_length
=
emotion_labels
.
length
;
let
data
=
[];
//loop through the activity labels
for
(
let
k
=
0
;
k
<
emotion_label_length
;
k
++
)
{
let
label
=
emotion_labels
[
k
];
let
datapoints
=
[];
let
count
=
0
;
//loop through the activity frame groups
for
(
let
key
in
lecture_emotion_frame_group_percentages
)
{
let
frame_group_details
=
lecture_emotion_frame_group_percentages
[
key
];
let
emotion_perct
=
frame_group_details
[
label
];
let
point
=
{
label
:
lecture_video_time_landmarks
[
count
],
y
:
emotion_perct
};
datapoints
.
push
(
point
);
count
++
;
}
let
obj
=
{
type
:
"
line
"
,
showInLegend
:
true
,
name
:
label
,
markerType
:
"
square
"
,
{
#
xValueFormatString
:
"
DD MMM, YYYY
"
,
#
}
xValueFormatString
:
"
hh:mm:ss
"
,
color
:
getRandomColor
(),
dataPoints
:
datapoints
};
data
.
push
(
obj
);
}
var
chart
=
new
CanvasJS
.
Chart
(
"
EmotionChartContainer
"
,
{
animationEnabled
:
true
,
theme
:
"
light2
"
,
title
:
{
text
:
"
Student Emotion Behavior
"
},
axisX
:
{
title
:
"
Duration
"
,
{
#
valueFormatString
:
"
DD MMM
"
,
#
}
valueFormatString
:
"
hh:mm:ss
"
,
crosshair
:
{
enabled
:
true
,
snapToDataPoint
:
true
}
},
axisY
:
{
title
:
"
Percentage
"
,
includeZero
:
true
,
crosshair
:
{
enabled
:
true
}
},
toolTip
:
{
shared
:
true
},
legend
:
{
cursor
:
"
pointer
"
,
verticalAlign
:
"
top
"
,
horizontalAlign
:
"
right
"
,
dockInsidePlotArea
:
true
,
itemclick
:
toogleDataSeries
},
data
:
data
});
chart
.
render
();
}
//this function will generate random colors
function
getRandomColor
()
{
var
letters
=
'
0123456789ABCDEF
'
;
var
color
=
'
#
'
;
for
(
var
i
=
0
;
i
<
6
;
i
++
)
{
color
+=
letters
[
Math
.
floor
(
Math
.
random
()
*
16
)];
}
return
color
;
}
//this function will toggle the content
function
toogleDataSeries
(
e
)
{
if
(
typeof
(
e
.
dataSeries
.
visible
)
===
"
undefined
"
||
e
.
dataSeries
.
visible
)
{
e
.
dataSeries
.
visible
=
false
;
}
else
{
e
.
dataSeries
.
visible
=
true
;
}
chart
.
render
();
}
});
});
</script>
</script>
...
@@ -787,122 +944,122 @@
...
@@ -787,122 +944,122 @@
</div>
</div>
<!-- end of frame tab -->
<!--graph tab -->
<!--graph tab -->
<div
class=
"tab-pane fade"
id=
"graph"
role=
"tabpanel"
<div
class=
"tab-pane fade"
id=
"graph"
role=
"tabpanel"
aria-labelledby=
"profile-tab"
>
aria-labelledby=
"profile-tab"
>
<!--card content -->
<!--card content -->
<div
class=
"card shadow mb-4 p-3"
>
<div
class=
"card shadow mb-4 p-3"
>
<!-- Card Header - Dropdown -->
<div
class=
"card-header py-3 d-flex flex-row align-items-center justify-content-between"
>
<h6
class=
"m-0 font-weight-bold text-primary"
>
Student
Activities
</h6>
<div
class=
"dropdown no-arrow"
>
<a
class=
"dropdown-toggle"
href=
"#"
role=
"button"
id=
"dropdownMenuLink"
data-toggle=
"dropdown"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<i
class=
"fas fa-ellipsis-v fa-sm fa-fw text-gray-400"
></i>
</a>
<div
class=
"dropdown-menu dropdown-menu-right shadow animated--fade-in"
aria-labelledby=
"dropdownMenuLink"
>
<div
class=
"dropdown-header"
>
Dropdown Header:
</div>
<a
class=
"dropdown-item"
href=
"#"
>
Action
</a>
<a
class=
"dropdown-item"
href=
"#"
>
Another action
</a>
<div
class=
"dropdown-divider"
></div>
<a
class=
"dropdown-item"
href=
"#"
>
Something else here
</a>
</div>
</div>
</div>
<!-- Card Body -->
<!-- Card Body -->
<div
class=
"card-body"
>
<div
class=
"card-body"
>
<div
class=
"chart-pie pt-4 pb-2"
>
<div
id=
"EmotionChartContainer"
<canvas
id=
"myPieChart"
></canvas>
style=
"height: 270px; max-width: 920px; margin: 0px auto;"
></div>
</div>
<div
class=
"mt-4 text-center small"
>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-primary"
></i>
Direct
</span>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-success"
></i>
Social
</span>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-info"
></i>
Referral
</span>
</div>
</div>
</div>
<!-- End of Card Body -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--2nd column -->
<!--2nd column -->
{#
<div
class=
"col-lg-6"
>
#}
<div
class=
"col-lg-6"
>
{#
<!--card content -->
#}
<!--card -->
{#
<div
class=
"card shadow mb-4"
>
#}
<div
class=
"card shadow mb-4"
>
{#
<!--card header -->
#}
<!--card header -->
{#
<div
class=
"card-header py-3"
>
#}
<div
class=
"card-header"
>
{#
<h5
class=
"m-0 font-weight-bold text-primary"
>
Frame Detections
</h5>
#}
<h5
class=
"m-0 font-weight-bold text-primary"
>
Integrated Evaluation
</h5>
{#
</div>
#}
</div>
{##}
{#
<!--card body -->
#}
{#
<div
class=
"text-center p-4"
id=
"detection_frames"
>
#}
{##}
{#
<!--no content message-->
#}
{#
<div
class=
"text-center p-2"
id=
"no_detection_message_content"
>
#}
{#
<span
class=
"font-italic"
>
No frame is selected
</span>
#}
{#
</div>
#}
{##}
{#
<div
class=
"text-left m-3"
id=
"detection_number_area"
hidden
>
#}
{#
<p>
No of detections:
<span
id=
"no_of_detections"
></span></p>
#}
{#
</div>
#}
{#
<!--the detection loader -->
#}
{#
<div
class=
"text-center p-2"
id=
"detection_loader"
hidden
>
#}
{#
<img
src=
"{% static 'FirstApp/images/ajax-loader.gif' %}"
#
}
{
#
alt=
"Loader"
>
#}
{#
</div>
#}
{#
</div>
#}
{#
</div>
#}
{##}
{#
<!--detection person card -->
#}
{#
<div
class=
"card shadow mb-4"
>
#}
{#
<!--card header -->
#}
{#
<div
class=
"card-header py-3"
>
#}
{#
<h5
class=
"m-0 font-weight-bold text-primary"
>
Detected Students (by emotion#}
{# type)
</h5>
#}
{#
</div>
#}
{##}
{#
<!--card body -->
#}
{#
<div
class=
"text-center p-4"
id=
"detection_students"
>
#}
{#
<!--activity type line -->
#}
{#
<div
class=
"text-center p-2"
id=
"activity_type"
hidden
>
#}
{#
<p>
Activity Type:
<span
class=
"font-weight-bold"
id=
"activity_type_text"
></span>
#}
{#
</p>
#}
{#
</div>
#}
{##}
{#
<!--no content message-->
#}
{#
<div
class=
"text-center p-2"
id=
"no_detection_student_content"
>
#}
{#
<span
class=
"font-italic"
>
No activity type is selected
</span>
#}
{#
</div>
#}
{##}
{#
<!--the detection student loader -->
#}
{#
<div
class=
"text-center p-2"
id=
"detection_student_loader"
hidden
>
#}
{#
<img
src=
"{% static 'FirstApp/images/ajax-loader.gif' %}"
#
}
{
#
alt=
"Loader"
>
#}
{#
</div>
#}
{##}
{#
</div>
#}
{#
</div>
#}
{#
</div>
#}
<!--card body -->
<div
class=
"card-body"
>
<div
class=
"text-center"
id=
"integrate_message"
>
<span
class=
"font-italic"
>
The integrated version student and lecturer evaluations will display here.
</span>
</div>
<!--button -->
<div
class=
"text-right m-4"
>
<button
type=
"button"
class=
"btn btn-outline-success"
id=
"integrate_emotion"
>
Process
</button>
</div>
</div>
</div>
</div>
<!--end of 2nd column -->
</div>
</div>
<!--2nd column -->
{#
<div
class=
"col-lg-6"
>
#}
{#
<!--card content -->
#}
{#
<div
class=
"card shadow mb-4"
>
#}
{#
<!--card header -->
#}
{#
<div
class=
"card-header py-3"
>
#}
{#
<h5
class=
"m-0 font-weight-bold text-primary"
>
Frame Detections
</h5>
#}
{#
</div>
#}
{##}
{#
<!--card body -->
#}
{#
<div
class=
"text-center p-4"
id=
"detection_frames"
>
#}
{##}
{#
<!--no content message-->
#}
{#
<div
class=
"text-center p-2"
id=
"no_detection_message_content"
>
#}
{#
<span
class=
"font-italic"
>
No frame is selected
</span>
#}
{#
</div>
#}
{##}
{#
<div
class=
"text-left m-3"
id=
"detection_number_area"
hidden
>
#}
{#
<p>
No of detections:
<span
id=
"no_of_detections"
></span></p>
#}
{#
</div>
#}
{#
<!--the detection loader -->
#}
{#
<div
class=
"text-center p-2"
id=
"detection_loader"
hidden
>
#}
{#
<img
src=
"{% static 'FirstApp/images/ajax-loader.gif' %}"
#
}
{
#
alt=
"Loader"
>
#}
{#
</div>
#}
{#
</div>
#}
{#
</div>
#}
{##}
{#
<!--detection person card -->
#}
{#
<div
class=
"card shadow mb-4"
>
#}
{#
<!--card header -->
#}
{#
<div
class=
"card-header py-3"
>
#}
{#
<h5
class=
"m-0 font-weight-bold text-primary"
>
Detected Students (by emotion#}
{# type)
</h5>
#}
{#
</div>
#}
{##}
{#
<!--card body -->
#}
{#
<div
class=
"text-center p-4"
id=
"detection_students"
>
#}
{#
<!--activity type line -->
#}
{#
<div
class=
"text-center p-2"
id=
"activity_type"
hidden
>
#}
{#
<p>
Activity Type:
<span
class=
"font-weight-bold"
id=
"activity_type_text"
></span>
#}
{#
</p>
#}
{#
</div>
#}
{##}
{#
<!--no content message-->
#}
{#
<div
class=
"text-center p-2"
id=
"no_detection_student_content"
>
#}
{#
<span
class=
"font-italic"
>
No activity type is selected
</span>
#}
{#
</div>
#}
{##}
{#
<!--the detection student loader -->
#}
{#
<div
class=
"text-center p-2"
id=
"detection_student_loader"
hidden
>
#}
{#
<img
src=
"{% static 'FirstApp/images/ajax-loader.gif' %}"
#
}
{
#
alt=
"Loader"
>
#}
{#
</div>
#}
{##}
{#
</div>
#}
{#
</div>
#}
{#
</div>
#}
{#
</div>
#}
<!-- end of 2nd row -->
<!-- end of 2nd row -->
<!--3rd row -->
<!--3rd row -->
...
@@ -941,32 +1098,32 @@
...
@@ -941,32 +1098,32 @@
{#
</div>
#}
{#
</div>
#}
<!--end of 1st column -->
<!--end of 1st column -->
{##}
<!--2nd column -->
{#
<!--2nd column -->
#}
<div
class=
"col-lg-6"
>
{#
<div
class=
"col-lg-6"
>
#}
<!--card -->
{#
<!--card -->
#}
<div
class=
"card shadow mb-4"
>
{#
<div
class=
"card shadow mb-4"
>
#}
<!--card header -->
{#
<!--card header -->
#}
<div
class=
"card-header"
>
{#
<div
class=
"card-header"
>
#}
<h5
class=
"m-0 font-weight-bold text-primary"
>
Integrated Evaluation
</h5>
{#
<h5
class=
"m-0 font-weight-bold text-primary"
>
Integrated Evaluation
</h5>
#}
</div>
{#
</div>
#}
{##}
<!--card body -->
{#
<!--card body -->
#}
<div
class=
"card-body"
>
{#
<div
class=
"card-body"
>
#}
<div
class=
"text-center"
id=
"integrate_message"
>
{#
<div
class=
"text-center"
id=
"integrate_message"
>
#}
<span
class=
"font-italic"
>
The integrated version student and lecturer evaluations will display here.
</span>
{#
<span
class=
"font-italic"
>
The integrated version student and lecturer evaluations will display here.
</span>
#}
</div>
{#
</div>
#}
{##}
<!--button -->
{#
<!--button -->
#}
<div
class=
"text-right m-4"
>
{#
<div
class=
"text-right m-4"
>
#}
<button
type=
"button"
class=
"btn btn-outline-success"
id=
"integrate_emotion"
>
{#
<button
type=
"button"
class=
"btn btn-outline-success"
id=
"integrate_emotion"
>
#}
Process
{# Process#}
</button>
{#
</button>
#}
</div>
{#
</div>
#}
</div>
{#
</div>
#}
</div>
{#
</div>
#}
</div>
{#
</div>
#}
<!--end of 2nd column -->
{#
<!--end of 2nd column -->
#}
</div>
</div>
<!--end of 3rd row -->
<!--end of 3rd row -->
...
...
FirstApp/templates/FirstApp/gaze.html
View file @
bcb44959
...
@@ -21,6 +21,11 @@
...
@@ -21,6 +21,11 @@
<!-- Core plugin JavaScript-->
<!-- Core plugin JavaScript-->
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<!-- canvasJS implementation -->
<script
src=
"https://canvasjs.com/assets/script/canvasjs.min.js"
></script>
<script
type=
"text/javascript"
>
<script
type=
"text/javascript"
>
...
@@ -31,10 +36,15 @@
...
@@ -31,10 +36,15 @@
var
global_lecturer_subject_index
=
0
;
var
global_lecturer_subject_index
=
0
;
var
global_lecturer_video_name
=
''
;
var
global_lecturer_video_name
=
''
;
var
lecturer_fps
=
0
;
var
lecturer_fps
=
0
;
var
lecture_gaze_frame_group_percentages
=
{};
//jquery
//jquery
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
//hide the 'integrate gaze' button
$
(
'
#integrate_gaze
'
).
hide
();
//select a particular subject
//select a particular subject
$
(
'
input[type=radio]
'
).
click
(
function
()
{
$
(
'
input[type=radio]
'
).
click
(
function
()
{
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
let
subject_id
=
$
(
this
).
attr
(
'
id
'
);
...
@@ -144,8 +154,8 @@
...
@@ -144,8 +154,8 @@
$
(
'
#video_name
'
).
text
(
video
.
video_name
);
$
(
'
#video_name
'
).
text
(
video
.
video_name
);
$
(
'
#video_duration
'
).
text
(
video
.
video_length
);
$
(
'
#video_duration
'
).
text
(
video
.
video_length
);
$
(
'
#video_date
'
).
text
(
video
.
date
);
$
(
'
#video_date
'
).
text
(
video
.
date
);
{
#
global_lecture_video_id
=
video
.
lecture_video_id
;
#
}
global_lecture_video_id
=
video
.
lecture_video_id
;
global_lecture_video_id
=
video
.
id
;
{
#
global_lecture_video_id
=
video
.
id
;
#
}
global_video_name
=
video
.
video_name
;
global_video_name
=
video
.
video_name
;
...
@@ -157,6 +167,9 @@
...
@@ -157,6 +167,9 @@
}
}
$
(
'
#video_modal
'
).
modal
();
$
(
'
#video_modal
'
).
modal
();
//show the 'integrate gaze' button
$
(
'
#integrate_gaze
'
).
show
();
}
}
...
@@ -247,9 +260,9 @@
...
@@ -247,9 +260,9 @@
//fetch the lecture recorded video name
//fetch the lecture recorded video name
fetch
(
'
http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=
'
+
global_lecturer
+
'
&subject=
'
+
global_subject
+
'
&date=
'
+
global_lecture_date
)
fetch
(
'
http://127.0.0.1:8000/get-lecture-recorded-video-name/?lecturer=
'
+
global_lecturer
+
'
&subject=
'
+
global_subject
+
'
&date=
'
+
global_lecture_date
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
then
((
out
)
=>
assignLecturerRecordedVideoName
(
out
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_1.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
{
#
global_lecturer_video_name
=
"
Test_2.mp4
"
;
#
}
...
@@ -520,6 +533,150 @@
...
@@ -520,6 +533,150 @@
});
});
//this function will handle the activity 'summary' button
$
(
'
#graph-tab
'
).
click
(
function
(
e
)
{
//display the graph loader
$
(
'
#graph_loader
'
).
attr
(
'
hidden
'
,
false
);
//fetch the video time landmark details
fetch
(
'
http://127.0.0.1:8000/get-lecture-video-summary-time-landmarks/?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
assignTimeLandmarks
(
out
.
response
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
//fetch the gaze summary details
fetch
(
'
http://127.0.0.1:8000/get-lecture-gaze-summary/?video_name=
'
+
global_video_name
)
.
then
((
res
)
=>
res
.
json
())
.
then
((
out
)
=>
gazeFrameGroupPercentages
(
out
,
e
))
.
catch
((
err
)
=>
alert
(
'
error:
'
+
err
));
});
//this function will assign lecture video time landmarks
function
assignTimeLandmarks
(
response
)
{
lecture_video_time_landmarks
=
response
;
}
//this function will handle the retrieved gaze frame group percentages
function
gazeFrameGroupPercentages
(
response
,
e
)
{
lecture_gaze_frame_group_percentages
=
response
.
frame_group_percentages
;
let
frame_landmarks
=
response
.
frame_landmarks
;
let
gaze_labels
=
response
.
gaze_labels
;
//render the chart onto the modal body
renderGazeChart
(
gaze_labels
);
}
//this function will call the chart function
function
renderGazeChart
(
gaze_labels
)
{
//get the activity label length
let
gaze_label_length
=
gaze_labels
.
length
;
let
data
=
[];
//loop through the activity labels
for
(
let
k
=
0
;
k
<
gaze_label_length
;
k
++
)
{
let
label
=
gaze_labels
[
k
];
let
datapoints
=
[];
let
count
=
0
;
//loop through the activity frame groups
for
(
let
key
in
lecture_gaze_frame_group_percentages
)
{
let
frame_group_details
=
lecture_gaze_frame_group_percentages
[
key
];
let
gaze_perct
=
frame_group_details
[
label
];
let
point
=
{
label
:
lecture_video_time_landmarks
[
count
],
y
:
gaze_perct
};
datapoints
.
push
(
point
);
count
++
;
}
let
obj
=
{
type
:
"
line
"
,
showInLegend
:
true
,
name
:
label
,
markerType
:
"
square
"
,
{
#
xValueFormatString
:
"
DD MMM, YYYY
"
,
#
}
xValueFormatString
:
"
hh:mm:ss
"
,
color
:
getRandomColor
(),
dataPoints
:
datapoints
};
data
.
push
(
obj
);
}
var
chart
=
new
CanvasJS
.
Chart
(
"
GazeChartContainer
"
,
{
animationEnabled
:
true
,
theme
:
"
light2
"
,
title
:
{
text
:
"
Student Gaze estimation Behavior
"
},
axisX
:
{
title
:
"
Duration
"
,
{
#
valueFormatString
:
"
DD MMM
"
,
#
}
valueFormatString
:
"
hh:mm:ss
"
,
crosshair
:
{
enabled
:
true
,
snapToDataPoint
:
true
}
},
axisY
:
{
title
:
"
Percentage
"
,
includeZero
:
true
,
crosshair
:
{
enabled
:
true
}
},
toolTip
:
{
shared
:
true
},
legend
:
{
cursor
:
"
pointer
"
,
verticalAlign
:
"
top
"
,
horizontalAlign
:
"
right
"
,
dockInsidePlotArea
:
true
,
itemclick
:
toogleDataSeries
},
data
:
data
});
chart
.
render
();
}
//this function will generate random colors
function
getRandomColor
()
{
var
letters
=
'
0123456789ABCDEF
'
;
var
color
=
'
#
'
;
for
(
var
i
=
0
;
i
<
6
;
i
++
)
{
color
+=
letters
[
Math
.
floor
(
Math
.
random
()
*
16
)];
}
return
color
;
}
//this function will toggle the content
function
toogleDataSeries
(
e
)
{
if
(
typeof
(
e
.
dataSeries
.
visible
)
===
"
undefined
"
||
e
.
dataSeries
.
visible
)
{
e
.
dataSeries
.
visible
=
false
;
}
else
{
e
.
dataSeries
.
visible
=
true
;
}
chart
.
render
();
}
});
});
</script>
</script>
...
@@ -771,53 +928,26 @@
...
@@ -771,53 +928,26 @@
aria-labelledby=
"profile-tab"
>
aria-labelledby=
"profile-tab"
>
<!--card content -->
<!--card content -->
<div
class=
"card shadow mb-4 p-3"
>
<div
class=
"card shadow mb-4 p-3"
>
<!-- Card Header - Dropdown -->
<div
class=
"card-header py-3 d-flex flex-row align-items-center justify-content-between"
>
<h6
class=
"m-0 font-weight-bold text-primary"
>
Student
Activities
</h6>
<div
class=
"dropdown no-arrow"
>
<a
class=
"dropdown-toggle"
href=
"#"
role=
"button"
id=
"dropdownMenuLink"
data-toggle=
"dropdown"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<i
class=
"fas fa-ellipsis-v fa-sm fa-fw text-gray-400"
></i>
</a>
<div
class=
"dropdown-menu dropdown-menu-right shadow animated--fade-in"
aria-labelledby=
"dropdownMenuLink"
>
<div
class=
"dropdown-header"
>
Dropdown Header:
</div>
<a
class=
"dropdown-item"
href=
"#"
>
Action
</a>
<a
class=
"dropdown-item"
href=
"#"
>
Another action
</a>
<div
class=
"dropdown-divider"
></div>
<a
class=
"dropdown-item"
href=
"#"
>
Something else here
</a>
</div>
</div>
</div>
<!-- Card Body -->
<!-- Card Body -->
<div
class=
"card-body"
>
<div
class=
"card-body"
>
<div
class=
"chart-pie pt-4 pb-2"
>
<div
id=
"GazeChartContainer"
<canvas
id=
"myPieChart"
></canvas>
style=
"height: 370px; max-width: 920px; margin: 0px auto;"
></div>
</div>
<div
class=
"mt-4 text-center small"
>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-primary"
></i>
Direct
</span>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-success"
></i>
Social
</span>
<span
class=
"mr-2"
>
<i
class=
"fas fa-circle text-info"
></i>
Referral
</span>
</div>
</div>
</div>
</div>
</div>
<!-- End of Card Body -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- end of 1st column -->
<!--2nd column -->
<!--2nd column -->
...
@@ -846,17 +976,11 @@
...
@@ -846,17 +976,11 @@
</div>
</div>
</div>
</div>
<!--end of 2nd column -->
<!--end of 2nd column -->
</div>
</div>
<!-- end of 2nd row -->
<!--3rd row -->
<div
class=
"row p-2"
>
</div>
{#
</div>
#}
<!--
end of 3r
d row -->
<!--
end of 2n
d row -->
</div>
</div>
...
...
FirstApp/templates/FirstApp/template.html
View file @
bcb44959
...
@@ -118,6 +118,7 @@
...
@@ -118,6 +118,7 @@
<div
id=
"collapseThree"
class=
"collapse"
aria-labelledby=
"headingThree"
data-parent=
"#accordionSidebar"
>
<div
id=
"collapseThree"
class=
"collapse"
aria-labelledby=
"headingThree"
data-parent=
"#accordionSidebar"
>
<div
class=
"bg-white py-2 collapse-inner rounded"
>
<div
class=
"bg-white py-2 collapse-inner rounded"
>
<h6
class=
"collapse-header"
>
Components:
</h6>
<h6
class=
"collapse-header"
>
Components:
</h6>
<a
class=
"collapse-item"
href=
"/summary/record"
>
Record Lecture
</a>
<a
class=
"collapse-item"
href=
"/summary/lecture"
>
Summarization
</a>
<a
class=
"collapse-item"
href=
"/summary/lecture"
>
Summarization
</a>
</div>
</div>
</div>
</div>
...
...
FirstApp/urls.py
View file @
bcb44959
...
@@ -192,6 +192,9 @@ urlpatterns = [
...
@@ -192,6 +192,9 @@ urlpatterns = [
# perform random task (delete later)
# perform random task (delete later)
url
(
r'^get-random-number/$'
,
api
.
TestRandom
.
as_view
()),
url
(
r'^get-random-number/$'
,
api
.
TestRandom
.
as_view
()),
# perform random task (delete later)
url
(
r'^display-upcoming-lectures/$'
,
api
.
DisplayUpcomingLecturesAPI
.
as_view
()),
...
...
LectureSummarizingApp/Voice Recorder.py
0 → 100644
View file @
bcb44959
import
sounddevice
as
sd
from
scipy.io.wavfile
import
write
import
wavio
as
wv
# Sampling frequency
freq
=
44100
# Recording duration
duration
=
10
# Start recorder with the given values of
# duration and sample frequency
recording
=
sd
.
rec
(
int
(
duration
*
freq
),
samplerate
=
freq
,
channels
=
2
)
# Record audio for the given number of seconds
sd
.
wait
()
# This will convert the NumPy array to an audio
# file with the given sampling frequency
write
(
"recording0.wav"
,
freq
,
recording
)
#Convert the NumPy array to audio file
wv
.
write
(
"recording1.wav"
,
recording
,
freq
,
sampwidth
=
2
)
\ No newline at end of file
LectureSummarizingApp/models.py
View file @
bcb44959
...
@@ -54,3 +54,4 @@ class LectureNotices (models.Model):
...
@@ -54,3 +54,4 @@ class LectureNotices (models.Model):
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
lecture_notice_id
return
self
.
lecture_notice_id
LectureSummarizingApp/templates/LectureSummarizingApp/RecordLecture.html
0 → 100644
View file @
bcb44959
{% extends 'FirstApp/template.html' %}
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Lecture Recording
</title>
</head>
<body>
% block javascript %}
{% load static %}
<!-- Bootstrap core JavaScript-->
<script
src=
"{% static 'FirstApp/vendor/jquery/jquery.min.js' %}"
></script>
<script
src=
"{% static 'FirstApp/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"
></script>
<!-- Page level plugins -->
<script
src=
"{% static 'FirstApp/vendor/datatables/jquery.dataTables.min.js' %}"
></script>
<script
src=
"{% static 'FirstApp/vendor/datatables/dataTables.bootstrap4.min.js' %}"
></script>
<!-- Page level custom scripts -->
<script
src=
"{% static 'FirstApp/js/demo/datatables-demo.js' %}"
></script>
<!-- Core plugin JavaScript-->
<script
src=
"{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"
></script>
<!-- Load TensorFlow.js -->
<script
src=
"https://unpkg.com/@tensorflow/tfjs"
></script>
<!-- Load Posenet -->
<script
src=
"https://unpkg.com/@tensorflow-models/posenet"
>
</script>
{% endblock %}
<div
id=
"wrapper"
>
<div
id=
"content-wrapper"
class=
"d-flex flex-column"
>
<div
id=
"content"
>
{% block 'container-fluid' %}
<div
class=
"container-fluid"
>
{% load static %}
<div
class=
"d-sm-flex align-items-center justify-content-between mb-4"
>
<h1
class=
"h3 mb-0 text-gray-800"
>
Lecture Record
</h1>
</div>
<div>
<button
TYPE=
"button"
class=
"btn btn-success audio_process"
>
Start Recording
</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
LectureSummarizingApp/urls.py
View file @
bcb44959
...
@@ -8,6 +8,7 @@ router = routers.DefaultRouter()
...
@@ -8,6 +8,7 @@ router = routers.DefaultRouter()
urlpatterns
=
[
urlpatterns
=
[
path
(
'lecture'
,
views
.
summarization
),
path
(
'lecture'
,
views
.
summarization
),
path
(
'record'
,
views
.
lectureRecord
),
# API to retrieve lecture summarizing details
# API to retrieve lecture summarizing details
...
...
LectureSummarizingApp/views.py
View file @
bcb44959
...
@@ -6,6 +6,14 @@ from .models import LectureAudio, LectureAudioNoiseRemoved, LectureSpeechToText,
...
@@ -6,6 +6,14 @@ from .models import LectureAudio, LectureAudioNoiseRemoved, LectureSpeechToText,
from
.serializer
import
LectureAudioSerializer
,
LectureAudioNoiseRemovedSerializer
,
LectureAudioSummarySerializer
,
\
from
.serializer
import
LectureAudioSerializer
,
LectureAudioNoiseRemovedSerializer
,
LectureAudioSummarySerializer
,
\
LectureSpeechToTextSerializer
,
LectureNoticesSerializer
LectureSpeechToTextSerializer
,
LectureNoticesSerializer
def
lectureRecord
(
request
):
lecture_audio
=
LectureAudio
.
objects
.
all
()
lecture_audio_ser
=
LectureAudioSerializer
(
lecture_audio
,
many
=
True
)
print
(
'lecture record data: '
,
lecture_audio_ser
.
data
)
return
render
(
request
,
"LectureSummarizationApp/RecordLecture.html"
)
# Views used in Lecture Summarization
# Views used in Lecture Summarization
...
@@ -108,4 +116,5 @@ class lectureSummaryList(APIView):
...
@@ -108,4 +116,5 @@ class lectureSummaryList(APIView):
lecture_audio_id
=
request
.
data
[
"lecture_audio_id"
],
lecture_audio_id
=
request
.
data
[
"lecture_audio_id"
],
notice_text
=
request
.
data
[
"notice_text"
]
notice_text
=
request
.
data
[
"notice_text"
]
)
.
save
()
)
.
save
()
return
Response
({
"response"
:
request
.
data
})
return
Response
({
"response"
:
request
.
data
})
\ No newline at end of file
integrated_slpes/urls.py
View file @
bcb44959
...
@@ -24,5 +24,6 @@ urlpatterns = [
...
@@ -24,5 +24,6 @@ urlpatterns = [
path
(
'attendance/'
,
include
(
'AttendanceApp.urls'
)),
path
(
'attendance/'
,
include
(
'AttendanceApp.urls'
)),
path
(
'lecturer/'
,
include
(
'MonitorLecturerApp.urls'
)),
path
(
'lecturer/'
,
include
(
'MonitorLecturerApp.urls'
)),
# path('lecturer/', include('MonitorLecturerApp.urls')),
# path('lecturer/', include('MonitorLecturerApp.urls')),
path
(
'summary/'
,
include
(
'LectureSummarizingApp.urls'
))
path
(
'summary/'
,
include
(
'LectureSummarizingApp.urls'
)),
path
(
'record/'
,
include
(
'LectureSummarizingApp.urls'
))
]
]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment