sakai-info 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,109 @@
1
+ # sakai-info/question_pool.rb
2
+ # SakaiInfo::QuestionPool library
3
+ #
4
+ # Created 2012-02-26 daveadams@gmail.com
5
+ # Last updated 2012-02-26 daveadams@gmail.com
6
+ #
7
+ # https://github.com/daveadams/sakai-info
8
+ #
9
+ # This software is public domain.
10
+ #
11
+
12
+ module SakaiInfo
13
+ class QuestionPool < SakaiObject
14
+ attr_reader :title, :owner, :description, :parent_pool_id, :dbrow
15
+
16
+ include ModProps
17
+ created_at_key :datecreated
18
+ created_by_key :ownerid
19
+ modified_at_key :lastmodifieddate
20
+ modified_by_key :lastmodifiedby
21
+
22
+ def initialize(dbrow)
23
+ @dbrow = dbrow
24
+
25
+ @id = dbrow[:questionpoolid]
26
+ @title = dbrow[:title]
27
+ @description = dbrow[:description]
28
+ @owner = User.find(dbrow[:ownerid])
29
+ @parent_pool_id = dbrow[:parentpoolid]
30
+ @parent_pool_id = nil if @parent_pool_id == 0
31
+ end
32
+
33
+ @@cache = {}
34
+ def self.find(id)
35
+ if @@cache[id].nil?
36
+ row = DB.connect[:sam_questionpool_t].filter(:questionpoolid => id).first
37
+ if row.nil?
38
+ raise ObjectNotFoundException.new(QuestionPool, id)
39
+ end
40
+ @@cache[id] = QuestionPool.new(row)
41
+ end
42
+ @@cache[id]
43
+ end
44
+
45
+ def self.find_by_user_id(user_id)
46
+ results = []
47
+ DB.connect[:sam_questionpool_t].filter(:ownerid => user_id).all.each do |row|
48
+ id = row[:questionpoolid]
49
+ @@cache[id] = QuestionPool.new(row)
50
+ results << @@cache[id]
51
+ end
52
+ results
53
+ end
54
+
55
+ def self.count_by_user_id(user_id)
56
+ DB.connect[:sam_questionpool_t].filter(:ownerid => user_id).count
57
+ end
58
+
59
+ def item_count
60
+ @item_count ||=
61
+ DB.connect[:sam_questionpoolitem_t].filter(:questionpoolid => @id).count
62
+ end
63
+
64
+ def parent
65
+ if not @parent_pool_id.nil?
66
+ @parent ||= QuestionPool.find(@parent_pool_id)
67
+ end
68
+ end
69
+
70
+ # serialization
71
+ def default_serialization
72
+ result = {
73
+ "id" => self.id,
74
+ "title" => self.title,
75
+ "owner" => self.owner.serialize(:summary),
76
+ "parent" => nil,
77
+ "item_count" => self.item_count
78
+ }
79
+ if not self.parent.nil?
80
+ result["parent"] = self.parent.serialize(:summary)
81
+ else
82
+ result.delete("parent")
83
+ end
84
+ result
85
+ end
86
+
87
+ def summary_serialization
88
+ result = {
89
+ "id" => self.id,
90
+ "title" => self.title,
91
+ "owner_eid" => self.owner.eid,
92
+ "parent_pool_id" => self.parent_pool_id,
93
+ "item_count" => self.item_count
94
+ }
95
+ if result["parent_pool_id"].nil?
96
+ result.delete("parent_pool_id")
97
+ end
98
+ result
99
+ end
100
+
101
+ def user_summary_serialization
102
+ {
103
+ "id" => self.id,
104
+ "title" => self.title,
105
+ "item_count" => self.item_count
106
+ }
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,535 @@
1
+ # sakai-info/quiz.rb
2
+ # SakaiInfo::Quiz library
3
+ #
4
+ # Created 2012-02-17 daveadams@gmail.com
5
+ # Last updated 2012-02-26 daveadams@gmail.com
6
+ #
7
+ # https://github.com/daveadams/sakai-info
8
+ #
9
+ # This software is public domain.
10
+ #
11
+
12
+ module SakaiInfo
13
+ class Quiz < SakaiObject
14
+ attr_reader :title, :site, :dbrow
15
+
16
+ include ModProps
17
+ created_by_key :createdby
18
+ created_at_key :createddate
19
+ modified_by_key :lastmodifiedby
20
+ modified_at_key :lastmodifieddate
21
+
22
+ # a note about quizzes:
23
+ # they do not link directly back to sites
24
+ # instead, they link back only via the sam_authzdata_t table
25
+ def initialize(dbrow, site = nil)
26
+ @site = nil
27
+ if site.is_a? String
28
+ begin
29
+ @site = Site.find(site)
30
+ rescue ObjectNotFoundException
31
+ @site = nil
32
+ end
33
+ elsif site.is_a? Site
34
+ @site = site
35
+ end
36
+
37
+ @id = dbrow[:id]
38
+ @title = dbrow[:title]
39
+ @dbrow = dbrow
40
+
41
+ if @site.nil?
42
+ # published quizzes map to site_id via the OWN_PUBLISHED_ASSESSMENT function
43
+ # pending quizzes map to site_id via the EDIT_ASSESSMENT function
44
+ DB.connect[:sam_authzdata_t].select(:distinct.sql_function(:agentid)).
45
+ where(:qualifierid => @id).
46
+ where(:functionid => ["OWN_PUBLISHED_ASSESSMENT","EDIT_ASSESSMENT"]).
47
+ all.each do |row|
48
+ begin
49
+ site = Site.find(row[:agentid])
50
+ @site = site
51
+ rescue ObjectNotFoundException
52
+ @site = nil
53
+ end
54
+ break if not @site.nil?
55
+ end
56
+ end
57
+ end
58
+
59
+ @@cache = {}
60
+ def self.find(id)
61
+ id = id.to_s
62
+ if @@cache[id].nil?
63
+ quiz = nil
64
+ begin
65
+ quiz = PendingQuiz.find(id)
66
+ rescue ObjectNotFoundException
67
+ begin
68
+ quiz = PublishedQuiz.find(id)
69
+ rescue ObjectNotFoundException
70
+ raise ObjectNotFoundException.new(Quiz, id)
71
+ end
72
+ end
73
+ @@cache[id] = quiz
74
+ end
75
+ @@cache[id]
76
+ end
77
+
78
+ def self.find_by_site_id(site_id)
79
+ {
80
+ "pending" => PendingQuiz.find_by_site_id(site_id),
81
+ "published" => PublishedQuiz.find_by_site_id(site_id)
82
+ }
83
+ end
84
+
85
+ def self.count_by_site_id(site_id)
86
+ {
87
+ "pending_count" => PendingQuiz.count_by_site_id(site_id),
88
+ "published_count" => PublishedQuiz.count_by_site_id(site_id)
89
+ }
90
+ end
91
+
92
+ def quiz_type
93
+ nil
94
+ end
95
+
96
+ def section_count
97
+ @section_count ||= QuizSection.count_by_quiz_id(@id)
98
+ end
99
+
100
+ def sections
101
+ @sections ||= QuizSection.find_by_quiz_id(@id)
102
+ end
103
+
104
+ def default_serialization
105
+ result = {
106
+ "id" => self.id,
107
+ "title" => self.title,
108
+ "site" => nil,
109
+ "type" => self.quiz_type,
110
+ "section_count" => self.section_count
111
+ }
112
+ if not self.site.nil?
113
+ result["site"] = self.site.serialize(:summary)
114
+ end
115
+ result
116
+ end
117
+
118
+ def summary_serialization
119
+ result = {
120
+ "id" => self.id,
121
+ "title" => self.title,
122
+ "site_id" => nil,
123
+ "type" => self.quiz_type
124
+ }
125
+ if not self.site.nil?
126
+ result["site_id"] = self.site.id
127
+ end
128
+ result
129
+ end
130
+
131
+ def site_summary_serialization
132
+ {
133
+ "id" => self.id,
134
+ "title" => self.title
135
+ }
136
+ end
137
+
138
+ def sections_serialization
139
+ {
140
+ "sections" => self.sections.collect{|s|s.serialize(:quiz_summary)}
141
+ }
142
+ end
143
+ end
144
+
145
+ class PendingQuiz < Quiz
146
+ @@cache = {}
147
+ def self.find(id)
148
+ id = id.to_s
149
+ if @@cache[id].nil?
150
+ row = DB.connect[:sam_assessmentbase_t].filter(:id => id.to_i).first
151
+ if row.nil?
152
+ raise ObjectNotFoundException.new(PendingQuiz, id)
153
+ end
154
+ @@cache[id] = PendingQuiz.new(row)
155
+ end
156
+ @@cache[id]
157
+ end
158
+
159
+ def self.query_by_site_id(site_id)
160
+ db = DB.connect
161
+ db[:sam_assessmentbase_t].
162
+ where(:id =>
163
+ db[:sam_authzdata_t].select(:qualifierid).
164
+ where(:agentid => site_id,
165
+ :functionid => "EDIT_ASSESSMENT"))
166
+ end
167
+
168
+ def self.find_by_site_id(site_id)
169
+ results = []
170
+ PendingQuiz.query_by_site_id(site_id).all.each do |row|
171
+ @@cache[row[:id]] = PendingQuiz.new(row, site_id)
172
+ results << @@cache[row[:id]]
173
+ end
174
+ results
175
+ end
176
+
177
+ def self.count_by_site_id(site_id)
178
+ PendingQuiz.query_by_site_id(site_id).count
179
+ end
180
+
181
+ def quiz_type
182
+ "pending"
183
+ end
184
+ end
185
+
186
+ class PublishedQuiz < Quiz
187
+ @@cache = {}
188
+ def self.find(id)
189
+ id = id.to_s
190
+ if @@cache[id].nil?
191
+ row = DB.connect[:sam_publishedassessment_t].filter(:id => id.to_i).first
192
+ if row.nil?
193
+ raise ObjectNotFoundException.new(PublishedQuiz, id)
194
+ end
195
+
196
+ @@cache[id] = PublishedQuiz.new(row)
197
+ end
198
+ @@cache[id]
199
+ end
200
+
201
+ def self.query_by_site_id(site_id)
202
+ db = DB.connect
203
+ db[:sam_publishedassessment_t].
204
+ where(:id =>
205
+ db[:sam_authzdata_t].select(:qualifierid).
206
+ where(:agentid => site_id,
207
+ :functionid => "OWN_PUBLISHED_ASSESSMENT"))
208
+ end
209
+
210
+ def self.find_by_site_id(site_id)
211
+ results = []
212
+ PublishedQuiz.query_by_site_id(site_id).all.each do |row|
213
+ @@cache[row[:id]] = PublishedQuiz.new(row, site_id)
214
+ results << @@cache[row[:id]]
215
+ end
216
+ results
217
+ end
218
+
219
+ def self.count_by_site_id(site_id)
220
+ PublishedQuiz.query_by_site_id(site_id).count
221
+ end
222
+
223
+ def quiz_type
224
+ "published"
225
+ end
226
+ end
227
+
228
+ class QuizSection < SakaiObject
229
+ attr_reader :dbrow, :quiz, :sequence, :title, :description, :typeid, :status
230
+
231
+ include ModProps
232
+ created_by_key :createdby
233
+ created_at_key :createddate
234
+ modified_by_key :lastmodifiedby
235
+ modified_at_key :lastmodifieddate
236
+
237
+ def initialize(dbrow)
238
+ @dbrow = dbrow
239
+
240
+ @id = dbrow[:sectionid]
241
+ @quiz = Quiz.find(dbrow[:assessmentid])
242
+ @sequence = dbrow[:sequence]
243
+ @title = dbrow[:title]
244
+ @description = dbrow[:description]
245
+ @typeid = dbrow[:typeid]
246
+ @status = dbrow[:status]
247
+ end
248
+
249
+ @@cache = {}
250
+ def self.find(id)
251
+ id = id.to_s
252
+ if @@cache[id].nil?
253
+ begin
254
+ @@cache[id] = PendingQuizSection.find(id)
255
+ rescue ObjectNotFoundException
256
+ begin
257
+ @@cache[id] = PublishedQuizSection.find(id)
258
+ rescue ObjectNotFoundException
259
+ raise ObjectNotFoundException(QuizSection, id)
260
+ end
261
+ end
262
+ end
263
+ @@cache[id]
264
+ end
265
+
266
+ def self.query_by_quiz_id(quiz_id)
267
+ table = if Quiz.find(quiz_id).quiz_type == "pending"
268
+ :sam_section_t
269
+ else
270
+ :sam_publishedsection_t
271
+ end
272
+ DB.connect[table].where(:assessmentid => quiz_id).order(:sequence)
273
+ end
274
+
275
+ def self.find_by_quiz_id(quiz_id)
276
+ section_class = if Quiz.find(quiz_id).quiz_type == "pending"
277
+ PendingQuizSection
278
+ else
279
+ PublishedQuizSection
280
+ end
281
+
282
+ QuizSection.query_by_quiz_id(quiz_id).all.collect do |row|
283
+ section_class.new(row)
284
+ end
285
+ end
286
+
287
+ def self.count_by_quiz_id(quiz_id)
288
+ QuizSection.query_by_quiz_id(quiz_id).count
289
+ end
290
+
291
+ def section_type
292
+ nil
293
+ end
294
+
295
+ def item_count
296
+ @item_count ||= QuizItem.count_by_section_id(@id)
297
+ end
298
+
299
+ def items
300
+ @items ||= QuizItem.find_by_section_id(@id)
301
+ end
302
+
303
+ def default_serialization
304
+ {
305
+ "id" => self.id,
306
+ "title" => self.title,
307
+ "quiz" => self.quiz.serialize(:summary),
308
+ "sequence" => self.sequence,
309
+ "item_count" => self.item_count,
310
+ "description" => self.description,
311
+ "type" => self.section_type,
312
+ "typeid" => self.typeid,
313
+ "status" => self.status
314
+ }
315
+ end
316
+
317
+ def summary_serialization
318
+ {
319
+ "id" => self.id,
320
+ "title" => self.title,
321
+ "quiz_id" => self.quiz.id,
322
+ "sequence" => self.sequence
323
+ }
324
+ end
325
+
326
+ def quiz_summary_serialization
327
+ result = summary_serialization
328
+ result.delete("quiz_id")
329
+ result
330
+ end
331
+
332
+ def items_serialization
333
+ {
334
+ "items" => self.items.collect{|i|i.serialize(:summary)}
335
+ }
336
+ end
337
+
338
+ def self.all_serializations
339
+ [:default, :items, :mod]
340
+ end
341
+ end
342
+
343
+ class PendingQuizSection < QuizSection
344
+ @@cache = {}
345
+ def self.find(id)
346
+ id = id.to_s
347
+ if @@cache[id].nil?
348
+ row = DB.connect[:sam_section_t].where(:sectionid => id).first
349
+ if row.nil?
350
+ raise ObjectNotFoundException(PendingQuizSection, id)
351
+ end
352
+
353
+ @@cache[id] = PendingQuizSection.new(row)
354
+ end
355
+ @@cache[id]
356
+ end
357
+
358
+ def section_type
359
+ "pending"
360
+ end
361
+ end
362
+
363
+ class PublishedQuizSection < QuizSection
364
+ @@cache = {}
365
+ def self.find(id)
366
+ id = id.to_s
367
+ if @@cache[id].nil?
368
+ row = DB.connect[:sam_publishedsection_t].where(:sectionid => id).first
369
+ if row.nil?
370
+ raise ObjectNotFoundException(PublishedQuizSection, id)
371
+ end
372
+
373
+ @@cache[id] = PublishedQuizSection.new(row)
374
+ end
375
+ @@cache[id]
376
+ end
377
+
378
+ def section_type
379
+ "published"
380
+ end
381
+ end
382
+
383
+ class QuizItem < SakaiObject
384
+ attr_reader :dbrow, :section, :quiz, :sequence, :typeid
385
+
386
+ include ModProps
387
+ created_by_key :createdby
388
+ created_at_key :createddate
389
+ modified_by_key :lastmodifiedby
390
+ modified_at_key :lastmodifieddate
391
+
392
+ def initialize(dbrow)
393
+ @dbrow = dbrow
394
+
395
+ @id = dbrow[:itemid]
396
+ @section = QuizSection.find(dbrow[:sectionid])
397
+ @quiz = @section.quiz
398
+ @sequence = dbrow[:sequence]
399
+ @typeid = dbrow[:typeid]
400
+ end
401
+
402
+ @@cache = {}
403
+ def self.find(id)
404
+ id = id.to_s
405
+ if @@cache[id].nil?
406
+ begin
407
+ @@cache[id] = PendingQuizItem.find(id)
408
+ rescue ObjectNotFoundException
409
+ begin
410
+ @@cache[id] = PublishedQuizItem.find(id)
411
+ rescue ObjectNotFoundException
412
+ raise ObjectNotFoundException(QuizItem, id)
413
+ end
414
+ end
415
+ end
416
+ @@cache[id]
417
+ end
418
+
419
+ def self.table_name_for_type(type)
420
+ if type == "pending"
421
+ :sam_item_t
422
+ else
423
+ :sam_publisheditem_t
424
+ end
425
+ end
426
+
427
+ def self.class_for_type(type)
428
+ if type == "pending"
429
+ PendingQuizItem
430
+ else
431
+ PublishedQuizItem
432
+ end
433
+ end
434
+
435
+ def self.query_by_section_id(section_id)
436
+ table = QuizItem.table_name_for_type(QuizSection.find(section_id).section_type)
437
+ DB.connect[table].where(:sectionid => section_id).order(:sequence)
438
+ end
439
+
440
+ def self.count_by_section_id(section_id)
441
+ QuizItem.query_by_section_id(section_id).count
442
+ end
443
+
444
+ def self.find_by_section_id(section_id)
445
+ item_class = QuizItem.class_for_type(QuizSection.find(section_id).section_type)
446
+ QuizItem.query_by_section_id(section_id).all.collect do |row|
447
+ item_class.new(row)
448
+ end
449
+ end
450
+
451
+ def self.query_by_quiz_id(quiz_id)
452
+ table = QuizItem.table_name_for_type(Quiz.find(quiz_id).quiz_type)
453
+ DB.connect[table].
454
+ where(:sectionid => Quiz.find(quiz_id).sections.collect{|s|s.id})
455
+ end
456
+
457
+ def self.count_by_quiz_id(quiz_id)
458
+ QuizItem.query_by_quiz_id(quiz_id).count
459
+ end
460
+
461
+ def self.find_by_quiz_id(quiz_id)
462
+ item_class = QuizItem.class_for_type(Quiz.find(quiz_id).quiz_type)
463
+ QuizItem.query_by_quiz_id(quiz_id).all.collect do |row|
464
+ item_class.new(row)
465
+ end
466
+ end
467
+
468
+ def item_type
469
+ nil
470
+ end
471
+
472
+ def default_serialization
473
+ {
474
+ "id" => self.id,
475
+ "quiz" => self.quiz.serialize(:summary),
476
+ "section" => self.section.serialize(:summary),
477
+ "sequence" => self.sequence,
478
+ "type" => self.item_type,
479
+ "typeid" => self.typeid
480
+ }
481
+ end
482
+
483
+ def summary_serialization
484
+ {
485
+ "id" => self.id,
486
+ "quiz_id" => self.quiz.id,
487
+ "section_id" => self.section.id
488
+ }
489
+ end
490
+
491
+ def self.all_serializations
492
+ [:default, :mod]
493
+ end
494
+ end
495
+
496
+ class PendingQuizItem < QuizItem
497
+ @@cache = {}
498
+ def self.find(id)
499
+ id = id.to_s
500
+ if @@cache[id].nil?
501
+ row = DB.connect[:sam_item_t].where(:itemid => id).first
502
+ if row.nil?
503
+ raise ObjectNotFoundException(PendingQuizItem, id)
504
+ end
505
+
506
+ @@cache[id] = PendingQuizItem.new(row)
507
+ end
508
+ @@cache[id]
509
+ end
510
+
511
+ def item_type
512
+ "pending"
513
+ end
514
+ end
515
+
516
+ class PublishedQuizItem < QuizItem
517
+ @@cache = {}
518
+ def self.find(id)
519
+ id = id.to_s
520
+ if @@cache[id].nil?
521
+ row = DB.connect[:sam_publisheditem_t].where(:itemid => id).first
522
+ if row.nil?
523
+ raise ObjectNotFoundException(PublishedQuizItem, id)
524
+ end
525
+
526
+ @@cache[id] = PublishedQuizItem.new(row)
527
+ end
528
+ @@cache[id]
529
+ end
530
+
531
+ def item_type
532
+ "published"
533
+ end
534
+ end
535
+ end