quiz_proctor_engine 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/proctor_conversations_controller.rb +6 -26
- data/app/controllers/proctored_exams_controller.rb +68 -10
- data/app/views/layouts/quiz_proctor.erb +25 -0
- data/app/views/quiz_proctor_engine/_plugin_settings.erb +2 -2
- data/config/routes.rb +1 -0
- data/lib/quiz_proctor_engine/version.rb +1 -1
- metadata +13 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e5df57adf4234792d236a87510ee85444fc55f8
|
4
|
+
data.tar.gz: 3a88e2002d1eaf1a8a7ff78de745bd50bce01a85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ea44bebfd87bc789163e001fe530ff81a30887a93fae3a884d69b343f61b9822902755f5b2f4e8de01a5f65222b824011146dc7cb442c3e35918da967a9aee8
|
7
|
+
data.tar.gz: 06c20e9eed5c091faf8024a5e78c9aca27102f96859873b479f053ba40a4e3882abad082843f337ab36c1d05016efc74dcefcd65b01622a51a6f78297eb51813
|
@@ -12,14 +12,17 @@
|
|
12
12
|
|
13
13
|
# You should have received a copy of the GNU Affero General Public License
|
14
14
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
-
require "httparty"
|
16
15
|
|
17
16
|
class ProctorConversationsController < ApplicationController
|
18
|
-
|
19
|
-
before_action :verify_messageable
|
17
|
+
skip_before_action :verify_authenticity_token
|
20
18
|
|
21
19
|
def initiate_conversation
|
22
20
|
proctor = User.find(params[:proctor_id])
|
21
|
+
cd = CustomData.find_by(user: proctor, namespace: "edu.au.exam")
|
22
|
+
if cd.nil? || params[:proctor_code] != cd.data["d"]["exam"]["proctor_code"]
|
23
|
+
render json: { error: "Unauthorized" }
|
24
|
+
return
|
25
|
+
end
|
23
26
|
student = User.find(params[:student_id])
|
24
27
|
message = Conversation.build_message(proctor, params[:body])
|
25
28
|
conversation = proctor.initiate_conversation([student], true, subject: params[:subject])
|
@@ -27,27 +30,4 @@ class ProctorConversationsController < ApplicationController
|
|
27
30
|
render json: { status: :ok }
|
28
31
|
end
|
29
32
|
|
30
|
-
private
|
31
|
-
|
32
|
-
def verify_messageable
|
33
|
-
headers = {
|
34
|
-
"Content-Type" => "application/json",
|
35
|
-
}
|
36
|
-
plugin = PluginSetting.find_by(name: "quiz_proctor")
|
37
|
-
|
38
|
-
query = {
|
39
|
-
student_id: params[:student_id],
|
40
|
-
proctor_code: params[:proctor_code],
|
41
|
-
unstarted: true,
|
42
|
-
}.to_query
|
43
|
-
|
44
|
-
quiz = HTTParty.get(
|
45
|
-
"#{plugin.settings[:adhesion_url]}/api/proctored_exams?#{query}",
|
46
|
-
headers: headers,
|
47
|
-
# verify: false,
|
48
|
-
)
|
49
|
-
if quiz.parsed_response["error"].present?
|
50
|
-
render json: { error: "Unauthorized" }
|
51
|
-
end
|
52
|
-
end
|
53
33
|
end
|
@@ -32,19 +32,77 @@ class ProctoredExamsController < ApplicationController
|
|
32
32
|
proctor_code: params[:proctor_code],
|
33
33
|
}.to_query
|
34
34
|
|
35
|
-
|
36
|
-
"#{plugin.settings[:
|
35
|
+
exam_request = HTTParty.get(
|
36
|
+
"#{plugin.settings[:adhesion_proctor_url]}/api/proctored_exams?#{query}",
|
37
37
|
headers: headers,
|
38
38
|
# verify: false,
|
39
|
-
)
|
40
|
-
|
41
|
-
|
39
|
+
).parsed_response["exam_request"]
|
40
|
+
|
41
|
+
if exam_request.nil?
|
42
|
+
flash[:error] = "You do not have an exam that is ready to start."
|
43
|
+
redirect_to proctored_exams_path
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
matched_code = false
|
48
|
+
proctor_id = nil
|
49
|
+
proctor_name = nil
|
50
|
+
code = params[:proctor_code]
|
51
|
+
users = Account.find(exam_request["testing_center_id"]).users
|
52
|
+
CustomData.where(user: users, namespace: "edu.au.exam").find_each do |cd|
|
53
|
+
user = users.detect { |u| u.id == cd.user_id }
|
54
|
+
if cd.data["d"]["exam"]["proctor_code"] == code
|
55
|
+
matched_code = true
|
56
|
+
proctor_id = user.id
|
57
|
+
proctor_name = user.name
|
58
|
+
break
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if !matched_code
|
63
|
+
flash[:error] = "Invalid proctor code."
|
42
64
|
redirect_to proctored_exams_path
|
43
|
-
|
44
|
-
quiz = quiz.parsed_response
|
45
|
-
session[:is_proctored] = true
|
46
|
-
session[:proctor_access_code] = quiz["proctor_access_code"]
|
47
|
-
redirect_to course_quiz_take_path quiz["quiz"]["course_id"], quiz["quiz"]["exam_id"]
|
65
|
+
return
|
48
66
|
end
|
67
|
+
|
68
|
+
query = {
|
69
|
+
proctor_id: proctor_id,
|
70
|
+
proctor_name: proctor_name,
|
71
|
+
}.to_query
|
72
|
+
|
73
|
+
# HTTParty is really bad and sends the put body wrong, so i send everything in the params
|
74
|
+
# RestClient does this better but I dont have RestClient so HTTParty it is.
|
75
|
+
HTTParty.put(
|
76
|
+
"#{plugin.settings[:adhesion_proctor_url]}/api/proctored_exams/#{exam_request['id']}?#{query}",
|
77
|
+
body: {},
|
78
|
+
headers: headers,
|
79
|
+
)
|
80
|
+
canvas_quiz = Quizzes::Quiz.find(exam_request["exam_id"])
|
81
|
+
|
82
|
+
session[:is_proctored] = true
|
83
|
+
session[:proctor_access_code] = canvas_quiz.access_code
|
84
|
+
redirect_to course_quiz_take_path exam_request["course_id"], exam_request["exam_id"]
|
85
|
+
end
|
86
|
+
|
87
|
+
def finish_quiz
|
88
|
+
headers = {
|
89
|
+
"Content-Type" => "application/json",
|
90
|
+
}
|
91
|
+
plugin = PluginSetting.find_by(name: "quiz_proctor")
|
92
|
+
|
93
|
+
query = {
|
94
|
+
student_id: @current_user.id,
|
95
|
+
update: true,
|
96
|
+
}.to_query
|
97
|
+
|
98
|
+
HTTParty.get(
|
99
|
+
"#{plugin.settings[:adhesion_proctor_url]}/api/proctored_exams?#{query}",
|
100
|
+
headers: headers,
|
101
|
+
# verify: false
|
102
|
+
)
|
103
|
+
# we wont need to handle the response for this anyway, hence the hardcoded ok value
|
104
|
+
# if it fails we will probably never know because the JavaScript
|
105
|
+
# that will handle the response will have been reloaded by the time this finishes.
|
106
|
+
render json: { status: "ok" }
|
49
107
|
end
|
50
108
|
end
|
@@ -32,6 +32,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
32
32
|
removePreviousAndNext(0, false, false);
|
33
33
|
})();
|
34
34
|
|
35
|
+
(function(){
|
36
|
+
addCustomEventListenerToSubmit(0, false);
|
37
|
+
})();
|
38
|
+
|
35
39
|
function removePreviousAndNext(tries, nextAlreadyRemoved, previousAlreadyRemoved){
|
36
40
|
|
37
41
|
if(tries > 100 || (nextAlreadyRemoved && previousAlreadyRemoved)) {
|
@@ -57,4 +61,25 @@ function removePreviousAndNext(tries, nextAlreadyRemoved, previousAlreadyRemoved
|
|
57
61
|
|
58
62
|
}
|
59
63
|
|
64
|
+
function addCustomEventListenerToSubmit(tries, finished) {
|
65
|
+
|
66
|
+
if (tries > 100 || finished) {
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
var foundButton = false;
|
70
|
+
var button = document.getElementById("submit_quiz_button");
|
71
|
+
if(button) {
|
72
|
+
foundButton = true;
|
73
|
+
button.addEventListener('click', function(){
|
74
|
+
$.ajax({
|
75
|
+
type: 'PUT',
|
76
|
+
url: '/proctored_exams',
|
77
|
+
})
|
78
|
+
});
|
79
|
+
}
|
80
|
+
setTimeout(function(){
|
81
|
+
addCustomEventListenerToSubmit(tries + 1, foundButton);
|
82
|
+
}, 100)
|
83
|
+
}
|
84
|
+
|
60
85
|
</script>
|
@@ -22,8 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
22
22
|
<td><%= f.text_field :proctor_secret %></td>
|
23
23
|
</tr>
|
24
24
|
<tr>
|
25
|
-
<td><%= f.blabel :
|
26
|
-
<td><%= f.text_field :
|
25
|
+
<td><%= f.blabel :adhesion_proctor_url, en: "Adhesion Proctor Url" %></td>
|
26
|
+
<td><%= f.text_field :adhesion_proctor_url %></td>
|
27
27
|
</tr>
|
28
28
|
</table>
|
29
29
|
<% end %>
|
data/config/routes.rb
CHANGED
@@ -17,5 +17,6 @@ Rails.application.routes.draw do
|
|
17
17
|
get "proctor_login" => "proctor_login#login"
|
18
18
|
get "proctored_exams" => "proctored_exams#show"
|
19
19
|
post "proctored_exams" => "proctored_exams#start_quiz"
|
20
|
+
put "proctored_exams" => "proctored_exams#finish_quiz"
|
20
21
|
post "proctor_conversations" => "proctor_conversations#initiate_conversation"
|
21
22
|
end
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quiz_proctor_engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dittonjs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.2
|
19
|
+
version: '4.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.1'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
32
|
+
version: '5.1'
|
27
33
|
description: Allows students to take canvas quizzes in a chromeless view, as well
|
28
34
|
as allow proctors to enter answers on behalf of a student
|
29
35
|
email:
|
@@ -71,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
77
|
version: '0'
|
72
78
|
requirements: []
|
73
79
|
rubyforge_project:
|
74
|
-
rubygems_version: 2.6.
|
80
|
+
rubygems_version: 2.6.11
|
75
81
|
signing_key:
|
76
82
|
specification_version: 4
|
77
83
|
summary: Allows students to take canvas quizzes in a chromeless view, as well as allow
|