mumuki-classroom 9.22.0 → 9.23.0
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/lib/mumuki/classroom/event/user_changed.rb +8 -4
- data/lib/mumuki/classroom/models/certificate.rb +15 -0
- data/lib/mumuki/classroom/models/concerns/course_member.rb +9 -0
- data/lib/mumuki/classroom/models/exam_authorization.rb +12 -0
- data/lib/mumuki/classroom/models/exam_authorization_request.rb +15 -0
- data/lib/mumuki/classroom/models.rb +3 -0
- data/lib/mumuki/classroom/sinatra/massive.rb +33 -14
- data/lib/mumuki/classroom/sinatra/students.rb +0 -6
- data/lib/mumuki/classroom/sinatra.rb +10 -1
- data/lib/mumuki/classroom/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cabe7b354830abd76c73425df9e9ff2c4f7fa806bb6dbc0cac68a319bd12e231
|
|
4
|
+
data.tar.gz: acc653411dc6f1a809d0439d93de48d02a64020bd2c446b32ab25afeaff7dd06
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f0c793f1362ca34c185acd9cd92dfc7bdc660ad84f79fcb96b564d88eba59e05270163ff78dcb1bb56aa7cb16b1eb08914316fff37fdcb4ca02dc1611f4cee1
|
|
7
|
+
data.tar.gz: 041020d946aaece5a110f039050486c0983401b6f42f67d899a328896222b6ab9debaeb6c6c6ec1b8b11940d26f0dcbf5c35ec5e69eee18ddacf0429195cc8c8
|
|
@@ -29,8 +29,11 @@ class Mumuki::Classroom::Event::UserChanged
|
|
|
29
29
|
if students.exists?
|
|
30
30
|
students.first.attach!
|
|
31
31
|
else
|
|
32
|
-
student = Mumuki::Classroom::Student.
|
|
33
|
-
|
|
32
|
+
student = Mumuki::Classroom::Student.new(
|
|
33
|
+
Mumuki::Classroom::Student
|
|
34
|
+
.attributes_from_uid(uid)
|
|
35
|
+
.merge(organization: organization, course: granted_slug.to_s))
|
|
36
|
+
student.save! validate: false
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
@@ -41,8 +44,9 @@ class Mumuki::Classroom::Event::UserChanged
|
|
|
41
44
|
|
|
42
45
|
def teacher_added(organization, user, granted_slug)
|
|
43
46
|
uid = user[:uid]
|
|
44
|
-
teacher = Mumuki::Classroom::Teacher.
|
|
45
|
-
teacher.
|
|
47
|
+
teacher = Mumuki::Classroom::Teacher.find_or_initialize_by(organization: organization, course: granted_slug.to_s, uid: uid)
|
|
48
|
+
teacher.assign_attributes(Mumuki::Classroom::Teacher.attributes_from_uid(uid))
|
|
49
|
+
teacher.save! validate: false
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
def teacher_removed(organization, user, granted_slug)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class Mumuki::Classroom::Certificate < Mumuki::Classroom::Document
|
|
2
|
+
include Mongoid::Timestamps
|
|
3
|
+
|
|
4
|
+
field :pg_id, type: Integer
|
|
5
|
+
field :code, type: String
|
|
6
|
+
field :certificate_program_id, type: Integer
|
|
7
|
+
field :organization, type: String
|
|
8
|
+
field :student, type: Hash
|
|
9
|
+
field :started_at, type: Time
|
|
10
|
+
field :ended_at, type: Time
|
|
11
|
+
|
|
12
|
+
create_index(pg_id: 1)
|
|
13
|
+
create_index(organization: 1, 'student.course': 1, 'student.uid': 1)
|
|
14
|
+
create_index(certificate_program_id: 1)
|
|
15
|
+
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module CourseMember
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
|
+
MANDATORY_FIELDS = %w(uid first_name last_name email)
|
|
5
|
+
|
|
4
6
|
included do
|
|
5
7
|
include Mongoid::Timestamps
|
|
6
8
|
|
|
@@ -15,6 +17,9 @@ module CourseMember
|
|
|
15
17
|
field :course, type: Mumukit::Auth::Slug
|
|
16
18
|
|
|
17
19
|
create_index({organization: 1, course: 1, uid: 1}, {unique: true})
|
|
20
|
+
|
|
21
|
+
validates_presence_of(*MANDATORY_FIELDS)
|
|
22
|
+
validates :email, email: true
|
|
18
23
|
end
|
|
19
24
|
|
|
20
25
|
def as_user(verified: true)
|
|
@@ -23,6 +28,10 @@ module CourseMember
|
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
class_methods do
|
|
31
|
+
def valid_attributes?(json)
|
|
32
|
+
MANDATORY_FIELDS.all? { |it| json[it].present? } && EmailValidator.valid?(json[:email])
|
|
33
|
+
end
|
|
34
|
+
|
|
26
35
|
def ensure_not_exists!(query)
|
|
27
36
|
existing_members = where(query)
|
|
28
37
|
raise Mumuki::Classroom::CourseMemberExistsError, {existing_members: existing_members.map(&:uid)}.to_json if existing_members.exists?
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Mumuki::Classroom::ExamAuthorization < Mumuki::Classroom::Document
|
|
2
|
+
field :pg_id, type: Integer
|
|
3
|
+
field :session_id, type: String
|
|
4
|
+
field :guide_slug, type: String
|
|
5
|
+
field :organization, type: String
|
|
6
|
+
field :student, type: Hash
|
|
7
|
+
field :started, type: Mongoid::Boolean
|
|
8
|
+
field :started_at, type: Time
|
|
9
|
+
|
|
10
|
+
create_index(pg_id: 1)
|
|
11
|
+
create_index(organization: 1, 'student.course': 1, guide_slug: 1, 'student.uid': 1)
|
|
12
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class Mumuki::Classroom::ExamAuthorizationRequest < Mumuki::Classroom::Document
|
|
2
|
+
include Mongoid::Timestamps
|
|
3
|
+
|
|
4
|
+
field :pg_id, type: Integer
|
|
5
|
+
field :status, type: String
|
|
6
|
+
field :guide_slug, type: String
|
|
7
|
+
field :organization, type: String
|
|
8
|
+
field :exam_registration_id, type: Integer
|
|
9
|
+
field :student, type: Hash
|
|
10
|
+
|
|
11
|
+
create_index(pg_id: 1)
|
|
12
|
+
create_index(organization: 1, 'student.course': 1, guide_slug: 1, 'student.uid': 1)
|
|
13
|
+
create_index(exam_registration_id: 1)
|
|
14
|
+
create_index(organization: 1, 'student.course': 1, 'student.uid': 1)
|
|
15
|
+
end
|
|
@@ -16,6 +16,9 @@ require_relative './models/student'
|
|
|
16
16
|
require_relative './models/teacher'
|
|
17
17
|
require_relative './models/notification'
|
|
18
18
|
require_relative './models/suggestion'
|
|
19
|
+
require_relative './models/certificate'
|
|
20
|
+
require_relative './models/exam_authorization'
|
|
21
|
+
require_relative './models/exam_authorization_request'
|
|
19
22
|
|
|
20
23
|
require_relative './models/sorting'
|
|
21
24
|
require_relative './models/searching'
|
|
@@ -37,13 +37,13 @@ class Mumuki::Classroom::App < Sinatra::Application
|
|
|
37
37
|
|
|
38
38
|
post '/students/detach' do
|
|
39
39
|
update_students! do |processed|
|
|
40
|
-
|
|
40
|
+
update_students_permissions_at_course! :detach, :remove, processed
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
post '/students/attach' do
|
|
45
45
|
update_students! do |processed|
|
|
46
|
-
|
|
46
|
+
update_students_permissions_at_course! :attach, :add, processed
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
@@ -98,7 +98,7 @@ class Mumuki::Classroom::App < Sinatra::Application
|
|
|
98
98
|
user = User.find_or_initialize_by(uid: member[:uid])
|
|
99
99
|
user.assign_attributes user_from_member_json(member)
|
|
100
100
|
user.add_permission! role, course_slug
|
|
101
|
-
user.verify_name!
|
|
101
|
+
user.verify_name! force: true
|
|
102
102
|
yield user if block_given?
|
|
103
103
|
end
|
|
104
104
|
|
|
@@ -143,20 +143,39 @@ class Mumuki::Classroom::App < Sinatra::Application
|
|
|
143
143
|
|
|
144
144
|
def create_members!(role, &block)
|
|
145
145
|
members_collection = collection_for role
|
|
146
|
-
|
|
147
|
-
existing_members =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
146
|
+
|
|
147
|
+
existing_members, non_existent_members = partion_existing_members_in_course(
|
|
148
|
+
members_collection,
|
|
149
|
+
massive_members_for(role))
|
|
150
|
+
|
|
151
|
+
valid_members, invalid_members = non_existent_members.partition do |member|
|
|
152
|
+
members_collection.valid_attributes? member
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
errored_members = existing_members + invalid_members
|
|
156
|
+
|
|
157
|
+
members_collection
|
|
158
|
+
.collection
|
|
159
|
+
.insert_many(valid_members.map { |member| with_organization_and_course member })
|
|
160
|
+
upsert_users! role, valid_members, &block
|
|
161
|
+
|
|
162
|
+
massive_response(valid_members, unprocessed_members_for(role), errored_members,
|
|
153
163
|
"#{role.to_s.pluralize.titleize} already belong to current course", status: :created)
|
|
154
164
|
end
|
|
155
165
|
|
|
156
|
-
def
|
|
157
|
-
|
|
166
|
+
def partion_existing_members_in_course(collection, massive_members)
|
|
167
|
+
existing_members = existing_members_in_course(collection, massive_members)
|
|
168
|
+
existing_members_uids = existing_members.map { |it| it[:uid] }
|
|
169
|
+
[
|
|
170
|
+
existing_members,
|
|
171
|
+
massive_members.reject { |it| existing_members_uids.include? it[:uid] }.uniq { |it| it[:uid] }
|
|
172
|
+
]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def existing_members_in_course(collection, massive_members)
|
|
176
|
+
collection.where(with_organization_and_course)
|
|
158
177
|
.in(uid: massive_members.map { |it| it[:uid] })
|
|
159
|
-
.map { |it|
|
|
178
|
+
.map { |it| collection.normalized_attributes_from_json(it) }
|
|
160
179
|
end
|
|
161
180
|
|
|
162
181
|
def update_students!
|
|
@@ -166,7 +185,7 @@ class Mumuki::Classroom::App < Sinatra::Application
|
|
|
166
185
|
students_does_not_belong_msg, status: :updated
|
|
167
186
|
end
|
|
168
187
|
|
|
169
|
-
def
|
|
188
|
+
def update_students_permissions_at_course!(method, action, students_uids)
|
|
170
189
|
Mumuki::Classroom::Student.send "#{method}_all_by!", students_uids, with_organization_and_course
|
|
171
190
|
User.where(uid: students_uids).each do |user|
|
|
172
191
|
user.send "#{action}_permission!", :student, course_slug
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
class Mumuki::Classroom::App < Sinatra::Application
|
|
2
2
|
helpers do
|
|
3
|
-
def normalize_student!
|
|
4
|
-
json_body[:email] = json_body[:email]&.downcase
|
|
5
|
-
json_body[:last_name] = json_body[:last_name]&.downcase&.titleize
|
|
6
|
-
json_body[:first_name] = json_body[:first_name]&.downcase&.titleize
|
|
7
|
-
end
|
|
8
|
-
|
|
9
3
|
def list_students(matcher)
|
|
10
4
|
authorize! :teacher
|
|
11
5
|
count, students = Sorting.aggregate(Mumuki::Classroom::Student, with_detached_and_search(matcher, Mumuki::Classroom::Student), paginated_params, query_params)
|
|
@@ -243,7 +243,12 @@ HTML
|
|
|
243
243
|
json = JSON.parse(error_message.message)
|
|
244
244
|
response.body = json.to_json
|
|
245
245
|
rescue
|
|
246
|
-
|
|
246
|
+
if error_message.is_a?(Mongoid::Errors::MongoidError)
|
|
247
|
+
message_text = error_message.summary
|
|
248
|
+
else
|
|
249
|
+
message_text = error_message.message
|
|
250
|
+
end
|
|
251
|
+
response.body = {message: message_text}.to_json
|
|
247
252
|
end
|
|
248
253
|
end
|
|
249
254
|
end
|
|
@@ -256,6 +261,10 @@ HTML
|
|
|
256
261
|
halt 400
|
|
257
262
|
end
|
|
258
263
|
|
|
264
|
+
error Mongoid::Errors::Validations do
|
|
265
|
+
halt 400
|
|
266
|
+
end
|
|
267
|
+
|
|
259
268
|
error ActiveRecord::RecordNotFound do
|
|
260
269
|
halt 404
|
|
261
270
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mumuki-classroom
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.
|
|
4
|
+
version: 9.23.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Franco Bulgarelli
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-11-
|
|
11
|
+
date: 2021-11-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -86,14 +86,14 @@ dependencies:
|
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 9.
|
|
89
|
+
version: 9.23.0
|
|
90
90
|
type: :runtime
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 9.
|
|
96
|
+
version: 9.23.0
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: mumukit-login
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -232,11 +232,14 @@ files:
|
|
|
232
232
|
- lib/mumuki/classroom/locales/pt.yml
|
|
233
233
|
- lib/mumuki/classroom/models.rb
|
|
234
234
|
- lib/mumuki/classroom/models/assignment.rb
|
|
235
|
+
- lib/mumuki/classroom/models/certificate.rb
|
|
235
236
|
- lib/mumuki/classroom/models/concerns/course_member.rb
|
|
236
237
|
- lib/mumuki/classroom/models/concerns/extensions.rb
|
|
237
238
|
- lib/mumuki/classroom/models/concerns/with_failed_submission_reprocess.rb
|
|
238
239
|
- lib/mumuki/classroom/models/concerns/with_submission_process.rb
|
|
239
240
|
- lib/mumuki/classroom/models/document.rb
|
|
241
|
+
- lib/mumuki/classroom/models/exam_authorization.rb
|
|
242
|
+
- lib/mumuki/classroom/models/exam_authorization_request.rb
|
|
240
243
|
- lib/mumuki/classroom/models/exercise.rb
|
|
241
244
|
- lib/mumuki/classroom/models/failed_submission.rb
|
|
242
245
|
- lib/mumuki/classroom/models/follower.rb
|