Index: openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml,v diff -u -r1.2.2.21 -r1.2.2.22 --- openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml 1 Apr 2020 15:03:43 -0000 1.2.2.21 +++ openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml 2 Apr 2020 12:53:00 -0000 1.2.2.22 @@ -55,8 +55,8 @@ Aktualisieren Drucken - Signatur - Erzeuge einen digitalen Fingerabdruck bei Pr�fungsabgabe als Beleg der unver�nderten Abgabe + Signatur + Erzeuge einen digitalen Fingerabdruck bei Pr�fungsabgabe als Beleg der unver�nderten Abgabe Aktuelle Signatur Abgegebene Signatur @@ -138,5 +138,8 @@ L�sung Online-Beaufsichtigung Verwende f�r diese Pr�fung eine Online-Beaufsichtigung - + Synchronisierte Abwicklung + Wird die angezeigte Bearbeitungszeit strikt vom Lehrenden vorgegeben, oder hat jeder Student die Anzeige seiner aktuellen Bearbeitsdauer, auch wenn er etwas sp�ter beginnt + Ver�ffentlichung der Pr�fung + seit der Ver�ffentlichung Index: openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml,v diff -u -r1.2.2.18 -r1.2.2.19 --- openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml 1 Apr 2020 15:03:43 -0000 1.2.2.18 +++ openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml 2 Apr 2020 12:53:00 -0000 1.2.2.19 @@ -57,8 +57,8 @@ Actual Signature Submission Signature - Signature - Provide a digital finger print of submitted answers as proof of submitted content + Signature + Provide a digital finger print of submitted answers as proof of submitted content Create Exam Review Exam @@ -157,5 +157,10 @@ Submission revision Solution Proctoring + Use E-Proctoring for this exam Proctoring Use E-Proctoring for this exam + Synchronized Exam + Is the exam duration strictly controlled by the lecturer, or does every student get his working time displayed, independent from his starting time. + Exam Published + since published Index: openacs-4/packages/xowf/lib/inclass-exam-answer.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/inclass-exam-answer.wf,v diff -u -r1.1.2.8 -r1.1.2.9 --- openacs-4/packages/xowf/lib/inclass-exam-answer.wf 1 Apr 2020 15:03:43 -0000 1.1.2.8 +++ openacs-4/packages/xowf/lib/inclass-exam-answer.wf 2 Apr 2020 12:53:00 -0000 1.1.2.9 @@ -282,17 +282,22 @@ #:msg set_title-set_parameter-MenuBar-[$obj state] ::xo::cc set_parameter MenuBar 0 ::xo::cc set_parameter template_file view-plain-master - + if {[$obj property proctor 0]} { template::set_css_property -class header -property display -value none template::set_css_property -class footer -property display -value none - template::set_css_property -class sidebar -property display -value none + template::set_css_property -class sidebar -property display -value none } if {[$parent_obj state] eq "published" && [$obj state] ne "done"} { + set synchronized [$parent_obj property synchronized] + if {$synchronized eq ""} {set synchronized 0} set target_time [::xowf::test_item::question_manager exam_target_time \ -manager $parent_obj \ - -instance $obj] + -base_time [expr { $synchronized + ? [$parent_obj last_modified] + : [$obj creation_date]}] \ + ] ::xo::cc set_parameter top_includelet [list countdown-timer -target_time $target_time] } } Index: openacs-4/packages/xowf/lib/inclass-exam.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/inclass-exam.wf,v diff -u -r1.1.2.12 -r1.1.2.13 --- openacs-4/packages/xowf/lib/inclass-exam.wf 1 Apr 2020 17:05:20 -0000 1.1.2.12 +++ openacs-4/packages/xowf/lib/inclass-exam.wf 2 Apr 2020 12:53:00 -0000 1.1.2.13 @@ -171,7 +171,7 @@ }] # # We could send answer link ("aLink") as well this way, but we - # want to keep the link short, therefore we handle the proctor + # want to keep the link short, therefore, we handle the proctor # link inside the www-answer method. # } @@ -250,10 +250,8 @@ if {$state eq "published"} { set src [$obj pretty_link -query m=qrcode] set qrCode [subst {
}] - set total_minutes [::xowf::test_item::question_manager total_minutes $combined_form_info] - set publish_time [::xo::db::tcl_date [$obj last_modified] tz] - set target_time [clock format [expr {[clock scan $publish_time] + $total_minutes*60}] \ - -format %Y-%m-%dT%H:%M:%S] + set target_time [xowf::test_item::question_manager exam_target_time \ + -manager $obj -base_time [$obj last_modified]] set countdownHTML [xowf::test_item::answer_manager countdown_timer \ -target_time $target_time -id "countdown"] } @@ -497,7 +495,7 @@ # # Redirect the exam to an iframe for implementing proctoring. The # basic idea is that the web application turns on the camera and - # keeps the iframe while the user is iterating throught the exam. + # keeps the iframe while the user is iterating through the exam. # The line "

You are being proctored!

" is just a # placeholder and has to be replaced with real code. # @@ -507,8 +505,8 @@ ::xo::cc set_parameter MenuBar 0 return [:www-view [subst { - [real-proctering-code] -

You are being proctored!

+ +

You ([xo::cc user_id]) are being proctored in exam ${:object_id}!

}]] } Index: openacs-4/packages/xowf/tcl/test-item-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/test-item-procs.tcl,v diff -u -r1.7.2.42 -r1.7.2.43 --- openacs-4/packages/xowf/tcl/test-item-procs.tcl 1 Apr 2020 15:03:43 -0000 1.7.2.42 +++ openacs-4/packages/xowf/tcl/test-item-procs.tcl 2 Apr 2020 12:53:00 -0000 1.7.2.43 @@ -1281,7 +1281,7 @@ ######################################################################## - :public method get_duration {revision_sets} { + :public method get_duration {{-exam_published_time ""} revision_sets} { # # Get the duration from a set of revisions and return a dict # containing "from", "fromClock","to", "toClock", and "duration" @@ -1297,6 +1297,13 @@ dict set r to [clock format $toClock -format "%H:%M:%S"] set timeDiff [expr {$toClock - $fromClock}] dict set r duration "[expr {$timeDiff/60}]m [expr {$timeDiff%60}]s" + if {$exam_published_time ne ""} { + set examPublishedClock [clock scan [::xo::db::tcl_date $exam_published_time tz]] + dict set r examPublishedClock $examPublishedClock + dict set r examPublished [clock format $examPublishedClock -format "%H:%M:%S"] + set epTimeDiff [expr {$toClock - $examPublishedClock}] + dict set r examPublishedDuration "[expr {$epTimeDiff/60}]m [expr {$epTimeDiff%60}]s" + } return $r } @@ -1330,6 +1337,15 @@ } ######################################################################## + :method last_time_in_state { -obj:object -state:required } { + set result "" + foreach ps [$obj get_revision_sets] { + if {$state eq [ns_set get $ps state]} { + set result [ns_set get $ps creation_date] + } + } + return $result + } :public method runtime_panel { {-revision_id ""} @@ -1404,20 +1420,29 @@ if {$revision_id eq ""} { set revision_sets [:revisions_up_to $revision_sets $live_revision_id] } - set duration [xowf::test_item::answer_manager get_duration $revision_sets] - set IPs [xowf::test_item::answer_manager get_IPs $revision_sets] + set last_published [:last_time_in_state -obj [$answerObj parent_id] -state published] + set duration [:get_duration -exam_published_time $last_published $revision_sets] + set IPs [:get_IPs $revision_sets] set state [$answerObj state] if {$state eq "done"} { set submission_info "#xowf.submitted#" } else { set submission_info "#xowf.not_submitted# ($page_info)" } + if {[dict exists $duration examPublished]} { + set publishedInfo "#xowf.Exam_published#: [dict get $duration examPublished]
" + set extraDurationInfo " - #xowf.since_published#: [dict get $duration examPublishedDuration]" + } else { + set publishedInfo "" + set extraDurationInfo "" + } set HTML [subst { + $publishedInfo $revisionDetails
#xowf.Status#: $submission_info
#xowf.Duration#: [dict get $duration from] - [dict get $duration to] - ([dict get $duration duration])
+ ([dict get $duration duration]$extraDurationInfo)
IP: $IPs }] return $HTML @@ -1725,7 +1750,10 @@ {-target_time:required} {-id:required} } { - # new Date('1995-12-17T03:24:00') + # + # Accepted formats for target_time, determined by JavaScript + # ISO 8601, e.g. YYYY-MM-DDTHH:mm:ss.sss" + template::add_body_script -script [subst { var countdown_target_date = new Date('$target_time').getTime(); var countdown_days, countdown_hours, countdown_minutes, countdown_seconds; @@ -1979,13 +2007,32 @@ return $minutes } - :public method exam_target_time {-manager:object -instance:object} { + :public method exam_target_time {-manager:object -base_time} { + # + # Calculate the exam target time (finishing time) based on the + # duration of the exam plus the provided base_time (which is in + # the format returned by SQL) + # + # @param manager exam workflow + # @param base_time time in SQL format + # set combined_form_info [:combined_question_form $manager] set total_minutes [::xowf::test_item::question_manager total_minutes $combined_form_info] - set creation_time [::xo::db::tcl_date [$instance creation_date] tz] - set target_time [clock format [expr {[clock scan $creation_time] + $total_minutes*60}] \ + + # Use "try" for backward compatibility, versions before + # factional seconds. TODO: remove me. + try { + set base_clock [clock scan [::xo::db::tcl_date $base_time tz secfrac]] + if {[string length $secfrac] > 3} { + set secfrac [string range $secfrac 0 2] + } + } on error {errorMsg} { + set base_clock [clock scan [::xo::db::tcl_date $base_time tz]] + set secfrac 0 + } + set target_time [clock format [expr {$base_clock + $total_minutes*60}] \ -format %Y-%m-%dT%H:%M:%S] - return $target_time + return ${target_time}.$secfrac } :public method current_question_form { Index: openacs-4/packages/xowf/www/prototypes/select_question.form.page =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/select_question.form.page,v diff -u -r1.1.2.4 -r1.1.2.5 --- openacs-4/packages/xowf/www/prototypes/select_question.form.page 1 Apr 2020 15:03:43 -0000 1.1.2.4 +++ openacs-4/packages/xowf/www/prototypes/select_question.form.page 2 Apr 2020 12:53:00 -0000 1.1.2.5 @@ -4,13 +4,14 @@ -title "Select Question" \ -anon_instances f \ -text {} \ - -form {{
@question@ @shuffle_items@ @signature@ @proctoring@
} text/html} \ + -form {{
@question@ @shuffle_items@ @synchronized@ @signature@ @proctoring@
} text/html} \ -form_constraints { @cr_fields:hidden {_title:text,label=#xowf.online-exam-name#,default=#xowf.online-exam-default_name#} {question:form_page,multiple=true,form=en:TestItemText.form|en:TestItemShortText.form|en:TestItemMC.form|en:TestItemSC.form|en:TestItemUpload.form|en:TestItemReorder.form,required,help_text=#xowf.select_question_help_text#,label=#xowiki.questions#} {shuffle_items:boolean,horizontal=true,label=#xowf.randomized_items#,help_text=#xowf.randomized_items_help_text#} - {signature:boolean,horizontal=true,default=f,label=#xowf.signature#,help_text=#xowf.signature_help_text#} + {synchronized:boolean,horizontal=true,default=f,label=#xowf.Synchronized#,help_text=#xowf.Synchronized_help_text#} + {signature:boolean,horizontal=true,default=f,label=#xowf.Signature#,help_text=#xowf.Signature_help_text#} {proctoring:boolean,horizontal=true,default=f,label=#xowf.Proctoring#,help_text=#xowf.Proctoring_help_text#} _description:omit _page_order:omit }