mumuki-classroom 8.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +661 -0
- data/README.md +371 -0
- data/Rakefile +29 -0
- data/lib/mumuki/classroom.rb +56 -0
- data/lib/mumuki/classroom/collection.rb +10 -0
- data/lib/mumuki/classroom/engine.rb +8 -0
- data/lib/mumuki/classroom/event.rb +4 -0
- data/lib/mumuki/classroom/event/user_changed.rb +54 -0
- data/lib/mumuki/classroom/locales/en.yml +3 -0
- data/lib/mumuki/classroom/locales/es-CL.yml +3 -0
- data/lib/mumuki/classroom/locales/es.yml +3 -0
- data/lib/mumuki/classroom/locales/pt.yml +3 -0
- data/lib/mumuki/classroom/models.rb +22 -0
- data/lib/mumuki/classroom/models/assignment.rb +148 -0
- data/lib/mumuki/classroom/models/concerns/course_member.rb +53 -0
- data/lib/mumuki/classroom/models/concerns/extensions.rb +90 -0
- data/lib/mumuki/classroom/models/concerns/with_failed_submission_reprocess.rb +74 -0
- data/lib/mumuki/classroom/models/concerns/with_submission_process.rb +148 -0
- data/lib/mumuki/classroom/models/document.rb +12 -0
- data/lib/mumuki/classroom/models/exercise.rb +7 -0
- data/lib/mumuki/classroom/models/failed_submission.rb +16 -0
- data/lib/mumuki/classroom/models/follower.rb +19 -0
- data/lib/mumuki/classroom/models/guide_progress.rb +57 -0
- data/lib/mumuki/classroom/models/last_assignment.rb +7 -0
- data/lib/mumuki/classroom/models/message.rb +32 -0
- data/lib/mumuki/classroom/models/notification.rb +52 -0
- data/lib/mumuki/classroom/models/reporting.rb +24 -0
- data/lib/mumuki/classroom/models/searching.rb +60 -0
- data/lib/mumuki/classroom/models/searching/guide_progress.rb +90 -0
- data/lib/mumuki/classroom/models/sorting.rb +92 -0
- data/lib/mumuki/classroom/models/sorting/guide_progress.rb +147 -0
- data/lib/mumuki/classroom/models/sorting/student.rb +45 -0
- data/lib/mumuki/classroom/models/sorting/total_stats_sort_by.rb +5 -0
- data/lib/mumuki/classroom/models/student.rb +88 -0
- data/lib/mumuki/classroom/models/submission.rb +62 -0
- data/lib/mumuki/classroom/models/suggestion.rb +35 -0
- data/lib/mumuki/classroom/models/teacher.rb +3 -0
- data/lib/mumuki/classroom/permissions_diff.rb +83 -0
- data/lib/mumuki/classroom/reports.rb +4 -0
- data/lib/mumuki/classroom/reports/formats.rb +35 -0
- data/lib/mumuki/classroom/sinatra.rb +301 -0
- data/lib/mumuki/classroom/sinatra/courses.rb +157 -0
- data/lib/mumuki/classroom/sinatra/errors.rb +13 -0
- data/lib/mumuki/classroom/sinatra/exams.rb +71 -0
- data/lib/mumuki/classroom/sinatra/followers.rb +29 -0
- data/lib/mumuki/classroom/sinatra/guides.rb +79 -0
- data/lib/mumuki/classroom/sinatra/manual_evaluation.rb +16 -0
- data/lib/mumuki/classroom/sinatra/massive.rb +206 -0
- data/lib/mumuki/classroom/sinatra/messages.rb +52 -0
- data/lib/mumuki/classroom/sinatra/notifications.rb +29 -0
- data/lib/mumuki/classroom/sinatra/organization.rb +7 -0
- data/lib/mumuki/classroom/sinatra/pagination.rb +13 -0
- data/lib/mumuki/classroom/sinatra/permissions.rb +9 -0
- data/lib/mumuki/classroom/sinatra/ping.rb +7 -0
- data/lib/mumuki/classroom/sinatra/searching.rb +27 -0
- data/lib/mumuki/classroom/sinatra/students.rb +111 -0
- data/lib/mumuki/classroom/sinatra/suggestions.rb +17 -0
- data/lib/mumuki/classroom/sinatra/teachers.rb +14 -0
- data/lib/mumuki/classroom/version.rb +5 -0
- data/lib/mumuki/profile.rb +17 -0
- data/lib/mumuki/views/threads.html.erb +43 -0
- data/lib/tasks/mumuki/messages.rake +20 -0
- data/lib/tasks/mumuki/resubmissions.rake +15 -0
- data/lib/tasks/mumuki/students.rake +31 -0
- data/lib/tasks/mumuki/submissions.rake +17 -0
- data/lib/tasks/mumuki/user_permissions.rake +17 -0
- metadata +291 -0
data/README.md
ADDED
@@ -0,0 +1,371 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/mumuki/mumuki-classroom-api.svg?branch=master)](https://travis-ci.org/mumuki/mumuki-classroom-api)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/mumuki/mumuki-classroom-api/badges/gpa.svg)](https://codeclimate.com/github/mumuki/mumuki-classroom-api)
|
3
|
+
[![Test Coverage](https://codeclimate.com/github/mumuki/mumuki-classroom-api/badges/coverage.svg)](https://codeclimate.com/github/mumuki/mumuki-classroom-api)
|
4
|
+
[![Issue Count](https://codeclimate.com/github/mumuki/mumuki-classroom-api/badges/issue_count.svg)](https://codeclimate.com/github/mumuki/mumuki-classroom-api)
|
5
|
+
|
6
|
+
# Mumuki Classroom (API)
|
7
|
+
> Tools for tracking students' progress within Mumuki
|
8
|
+
|
9
|
+
## Preparing environment
|
10
|
+
|
11
|
+
### 1. Install essentials and base libraries
|
12
|
+
|
13
|
+
> First, we need to install some software: MongoDB and some common Ruby on Rails native dependencies
|
14
|
+
|
15
|
+
#### 1. Install Mongo 3.4
|
16
|
+
|
17
|
+
[This process depends on you OS](https://docs.mongodb.com/v3.4/installation/). On ubuntu, follow these instructions:
|
18
|
+
|
19
|
+
```sh
|
20
|
+
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 &&
|
21
|
+
echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list &&
|
22
|
+
sudo apt-get update &&
|
23
|
+
apt-get remove --purge mongo* -y &&
|
24
|
+
apt-get autoremove -y &&
|
25
|
+
apt-get install mongodb-org -y
|
26
|
+
```
|
27
|
+
|
28
|
+
And then `reboot` your machine.
|
29
|
+
|
30
|
+
#### 2. Install ruby essentials
|
31
|
+
|
32
|
+
```bash
|
33
|
+
sudo apt-get install autoconf curl git build-essential libssl-dev autoconf bison libreadline6 libreadline6-dev zlib1g zlib1g-dev rabbitmq-server
|
34
|
+
```ruby
|
35
|
+
|
36
|
+
### 2. Install rbenv
|
37
|
+
|
38
|
+
> [rbenv](https://github.com/rbenv/rbenv) is a ruby versions manager, similar to rvm, nvm, and so on.
|
39
|
+
|
40
|
+
```bash
|
41
|
+
curl https://raw.githubusercontent.com/rbenv/rbenv-installer/master/bin/rbenv-installer | bash
|
42
|
+
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc # or .bash_profile
|
43
|
+
echo 'eval "$(rbenv init -)"' >> ~/.bashrc # or .bash_profile
|
44
|
+
```
|
45
|
+
|
46
|
+
### 3. Install ruby
|
47
|
+
|
48
|
+
> Now we have rbenv installed, we can install ruby and [bundler](http://bundler.io/)
|
49
|
+
|
50
|
+
```bash
|
51
|
+
rbenv install 2.3.1
|
52
|
+
rbenv global 2.3.1
|
53
|
+
rbenv rehash
|
54
|
+
gem install bundler
|
55
|
+
gem install escualo
|
56
|
+
```
|
57
|
+
|
58
|
+
### 4. Clone this repository
|
59
|
+
|
60
|
+
> Because, err... we need to clone this repostory before developing it :stuck_out_tongue:
|
61
|
+
|
62
|
+
```bash
|
63
|
+
git clone https://github.com/mumuki/mumuki-classroom-api classroom-api
|
64
|
+
cd classroom-api
|
65
|
+
```
|
66
|
+
|
67
|
+
## Installing and Running
|
68
|
+
|
69
|
+
### Quick start
|
70
|
+
|
71
|
+
If you want to start the server quickly in developer environment,
|
72
|
+
you can just do the following:
|
73
|
+
|
74
|
+
```bash
|
75
|
+
./devstart
|
76
|
+
```
|
77
|
+
|
78
|
+
This will install your dependencies and boot the server.
|
79
|
+
|
80
|
+
### Installing the server
|
81
|
+
|
82
|
+
If you just want to install dependencies, just do:
|
83
|
+
|
84
|
+
```
|
85
|
+
bundle install
|
86
|
+
```
|
87
|
+
|
88
|
+
### Running the server
|
89
|
+
|
90
|
+
You can boot the server by using the standard rackup command:
|
91
|
+
|
92
|
+
```
|
93
|
+
# using defaults from config/puma.rb and rackup default port 9292
|
94
|
+
bundle exec rackup
|
95
|
+
|
96
|
+
# changing port
|
97
|
+
bundle exec rackup -p 8080
|
98
|
+
|
99
|
+
# changing threads count
|
100
|
+
MUMUKI_CLASSROOM_API_THREADS=30 bundle exec rackup
|
101
|
+
```
|
102
|
+
|
103
|
+
Or you can also start it with `puma` command, which gives you more control:
|
104
|
+
|
105
|
+
```
|
106
|
+
# using defaults from config/puma.rb
|
107
|
+
bundle exec puma
|
108
|
+
|
109
|
+
# changing ports and threads count, using puma-specific options:
|
110
|
+
bundle exec puma -t 2:30 -p 8080
|
111
|
+
|
112
|
+
# changing ports and threads count, using environment variables:
|
113
|
+
MUMUKI_CLASSROOM_API_PORT=8080 MUMUKI_CLASSROOM_API_THREADS=30 bundle exec puma
|
114
|
+
```
|
115
|
+
|
116
|
+
## Running tests
|
117
|
+
|
118
|
+
```bash
|
119
|
+
bundle exec rspec
|
120
|
+
```
|
121
|
+
|
122
|
+
## Running tasks
|
123
|
+
|
124
|
+
```bash
|
125
|
+
# starts commands consumer
|
126
|
+
bundle exec rake commands:listen
|
127
|
+
|
128
|
+
# starts submissions consumer
|
129
|
+
bundle exec rake submissions:listen
|
130
|
+
|
131
|
+
# starts resubmissions consumer
|
132
|
+
bundle exec rake resubmissions:listen
|
133
|
+
```
|
134
|
+
|
135
|
+
## Running Reports
|
136
|
+
|
137
|
+
```bash
|
138
|
+
# registered and active users reports
|
139
|
+
bundle exec rake students:reports:registered[<organization>,<course>,<from>,<to>,<json|table|csv>]
|
140
|
+
bundle exec rake students:reports:active[<organization>,<course>,<from>,<to>,<json|table|csv>]
|
141
|
+
```
|
142
|
+
|
143
|
+
## Running Migrations
|
144
|
+
|
145
|
+
```bash
|
146
|
+
# migration_name is the name of the migration file in ./migrations/, without extension and the "migrate_" prefix
|
147
|
+
bundle exec rake db:migrate[<migration_name>]
|
148
|
+
```
|
149
|
+
|
150
|
+
## Api
|
151
|
+
|
152
|
+
|
153
|
+
### Add student to exam
|
154
|
+
|
155
|
+
**Minimal permission**: `janitor`
|
156
|
+
|
157
|
+
```
|
158
|
+
POST /api/courses/:course/exams/:exam_id/students/:uid
|
159
|
+
```
|
160
|
+
|
161
|
+
**Response**
|
162
|
+
```json
|
163
|
+
{
|
164
|
+
"status": "updated",
|
165
|
+
"id": "9d0045448aae977a"
|
166
|
+
}
|
167
|
+
```
|
168
|
+
**Forbidden Response**
|
169
|
+
```json
|
170
|
+
{
|
171
|
+
"status": 403,
|
172
|
+
"error": "Exception"
|
173
|
+
}
|
174
|
+
```
|
175
|
+
|
176
|
+
### Guides
|
177
|
+
|
178
|
+
|
179
|
+
**Minimal permission**: `teacher`
|
180
|
+
|
181
|
+
```
|
182
|
+
GET /api/courses/:course/guides
|
183
|
+
```
|
184
|
+
|
185
|
+
**Response**
|
186
|
+
```json
|
187
|
+
{
|
188
|
+
"guides": [
|
189
|
+
{
|
190
|
+
"slug": "sagrado-corazon-alcal/mumuki-guia-fundamentos-primeros-programas",
|
191
|
+
"name": "Primeros Programas",
|
192
|
+
"parent": {
|
193
|
+
"type": "Lesson",
|
194
|
+
"name": "Primeros Programas",
|
195
|
+
"position": 1,
|
196
|
+
"chapter": {
|
197
|
+
"id": 13,
|
198
|
+
"name": "Fundamentos"
|
199
|
+
}
|
200
|
+
},
|
201
|
+
"language": {
|
202
|
+
"name": "gobstones"
|
203
|
+
},
|
204
|
+
"lesson": {
|
205
|
+
"id": 13,
|
206
|
+
"name": "Fundamentos"
|
207
|
+
}
|
208
|
+
}
|
209
|
+
]
|
210
|
+
}
|
211
|
+
```
|
212
|
+
**Forbidden Response**
|
213
|
+
```json
|
214
|
+
{
|
215
|
+
"status": 403,
|
216
|
+
"error": "Exception"
|
217
|
+
}
|
218
|
+
```
|
219
|
+
|
220
|
+
### Courses
|
221
|
+
|
222
|
+
|
223
|
+
**Minimal permission**: `teacher`
|
224
|
+
|
225
|
+
```
|
226
|
+
GET /api/courses/
|
227
|
+
```
|
228
|
+
|
229
|
+
**Response**
|
230
|
+
```json
|
231
|
+
{
|
232
|
+
"courses": [
|
233
|
+
{
|
234
|
+
"uid": "staging-digitalhouse/2017-1",
|
235
|
+
"days": [
|
236
|
+
"Lunes"
|
237
|
+
],
|
238
|
+
"code": "1",
|
239
|
+
"shifts": [
|
240
|
+
"Mañana"
|
241
|
+
],
|
242
|
+
"period": "2017",
|
243
|
+
"description": "Curso de prueba",
|
244
|
+
"slug": "staging-digitalhouse/2017-1"
|
245
|
+
}
|
246
|
+
]
|
247
|
+
}
|
248
|
+
```
|
249
|
+
**Forbidden Response**
|
250
|
+
```json
|
251
|
+
{
|
252
|
+
"status": 403,
|
253
|
+
"error": "Exception"
|
254
|
+
}
|
255
|
+
```
|
256
|
+
|
257
|
+
### Students
|
258
|
+
|
259
|
+
**Minimal permission**: `teacher`
|
260
|
+
|
261
|
+
```
|
262
|
+
GET /api/courses/:course/students
|
263
|
+
```
|
264
|
+
```json
|
265
|
+
|
266
|
+
{
|
267
|
+
"students": [
|
268
|
+
{
|
269
|
+
"name": "johndoe",
|
270
|
+
"email": "johndoe@gmail.com",
|
271
|
+
"image_url": "https://s.gravatar.com/avatar/ca995a4f4ba1aafbd71a6403aa78635c?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fsa.png",
|
272
|
+
"social_id": "auth0|57e035e9e6379dd660dbcd",
|
273
|
+
"first_name": "John",
|
274
|
+
"last_name": "Doe",
|
275
|
+
"last_assignment": null,
|
276
|
+
"uid": "johndoe@gmail.com",
|
277
|
+
"created_at": "2016-09-19T19:01:11.000Z"
|
278
|
+
}
|
279
|
+
]
|
280
|
+
}
|
281
|
+
```
|
282
|
+
|
283
|
+
**Forbidden Response**
|
284
|
+
```json
|
285
|
+
{
|
286
|
+
"status": 403,
|
287
|
+
"error": "Exception"
|
288
|
+
}
|
289
|
+
```
|
290
|
+
|
291
|
+
### Students progress
|
292
|
+
|
293
|
+
**Minimal permission**: `teacher`
|
294
|
+
|
295
|
+
```
|
296
|
+
GET /api/courses/:course/students/:uid
|
297
|
+
```
|
298
|
+
```json
|
299
|
+
|
300
|
+
{
|
301
|
+
"guide_students_progress": [
|
302
|
+
{
|
303
|
+
"guide": {
|
304
|
+
"slug": "sagrado-corazon-alcal/mumuki-guia-fundamentos-primeros-programas",
|
305
|
+
"name": "Primeros Programas",
|
306
|
+
"parent": {
|
307
|
+
"type": "Lesson",
|
308
|
+
"name": "Primeros Programas",
|
309
|
+
"position": 1,
|
310
|
+
"chapter": {
|
311
|
+
"id": 13,
|
312
|
+
"name": "Fundamentos"
|
313
|
+
}
|
314
|
+
},
|
315
|
+
"language": {
|
316
|
+
"name": "gobstones"
|
317
|
+
}
|
318
|
+
},
|
319
|
+
"student": {
|
320
|
+
"uid": "john.doe@gmail.com",
|
321
|
+
"email": "john.doe@gmail.com",
|
322
|
+
"last_name": "Doe",
|
323
|
+
"first_name": "John"
|
324
|
+
},
|
325
|
+
"stats": {
|
326
|
+
"passed": 13,
|
327
|
+
"failed": 0,
|
328
|
+
"passed_with_warnings": 0
|
329
|
+
},
|
330
|
+
"last_assignment": {
|
331
|
+
"exercise": {
|
332
|
+
"id": 290,
|
333
|
+
"name": "Sacar Bolitas",
|
334
|
+
"number": 11
|
335
|
+
},
|
336
|
+
"submission": {
|
337
|
+
"id": "12345667890abcdg",
|
338
|
+
"status": "passed",
|
339
|
+
"result": "",
|
340
|
+
"content": "program {\r\n Mover(Sur)\r\n Sacar(Rojo)\r\n}",
|
341
|
+
"feedback": "",
|
342
|
+
"created_at": "2017-01-06T00:43:48.176Z",
|
343
|
+
"test_results": [
|
344
|
+
{
|
345
|
+
"title": null,
|
346
|
+
"status": "passed",
|
347
|
+
"result": "foo"
|
348
|
+
}
|
349
|
+
],
|
350
|
+
"submissions_count": 2,
|
351
|
+
"expectation_results": [
|
352
|
+
{
|
353
|
+
"binding": "program",
|
354
|
+
"inspection": "HasBinding",
|
355
|
+
"result": "passed"
|
356
|
+
}
|
357
|
+
]
|
358
|
+
}
|
359
|
+
}
|
360
|
+
}
|
361
|
+
]
|
362
|
+
}
|
363
|
+
```
|
364
|
+
|
365
|
+
**Forbidden Response**
|
366
|
+
```json
|
367
|
+
{
|
368
|
+
"status": 403,
|
369
|
+
"error": "Exception"
|
370
|
+
}
|
371
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Mumuki::Classroom'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
load 'rails/tasks/statistics.rake'
|
20
|
+
|
21
|
+
require 'bundler/gem_tasks'
|
22
|
+
|
23
|
+
require 'rspec/core'
|
24
|
+
require 'rspec/core/rake_task'
|
25
|
+
|
26
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
27
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
28
|
+
|
29
|
+
task default: :spec
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Mumuki
|
2
|
+
module Classroom
|
3
|
+
INDEXES = []
|
4
|
+
|
5
|
+
def self.create_indexes!
|
6
|
+
INDEXES.each { |it| it.create_indexes }
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.register_index!(clazz)
|
10
|
+
INDEXES << clazz
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
require 'mumukit/platform'
|
17
|
+
require 'mongoid'
|
18
|
+
require 'mumuki/domain'
|
19
|
+
require 'mumukit/login'
|
20
|
+
require 'mumukit/nuntius'
|
21
|
+
require 'mumukit/inspection'
|
22
|
+
|
23
|
+
I18n.load_translations_path File.join(__dir__, 'classroom', 'locales', '*.yml')
|
24
|
+
|
25
|
+
require_relative './profile'
|
26
|
+
|
27
|
+
require_relative './classroom/models'
|
28
|
+
require_relative './classroom/reports'
|
29
|
+
|
30
|
+
require_relative './classroom/collection'
|
31
|
+
require_relative './classroom/event'
|
32
|
+
require_relative './classroom/permissions_diff'
|
33
|
+
|
34
|
+
Mulang::Inspection.register_extension! Mumukit::Inspection::Css
|
35
|
+
|
36
|
+
Mumukit::Nuntius.configure do |c|
|
37
|
+
c.app_name = 'classroom'
|
38
|
+
end
|
39
|
+
|
40
|
+
Mumukit::Platform.configure do |config|
|
41
|
+
config.application = Mumukit::Platform.classroom_api
|
42
|
+
config.web_framework = Mumukit::Platform::WebFramework::Sinatra
|
43
|
+
end
|
44
|
+
|
45
|
+
class Mumukit::Platform::Model
|
46
|
+
def self.demongoize(object)
|
47
|
+
parse object
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.mongoize(object)
|
51
|
+
object.as_json
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
require_relative './classroom/sinatra'
|
56
|
+
require_relative './classroom/engine'
|