Index: openacs-4/packages/lors/tcl/lors-imscp-blackboard6-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/lors/tcl/lors-imscp-blackboard6-procs.tcl,v diff -u -N -r1.7 -r1.8 --- openacs-4/packages/lors/tcl/lors-imscp-blackboard6-procs.tcl 18 May 2005 17:19:46 -0000 1.7 +++ openacs-4/packages/lors/tcl/lors-imscp-blackboard6-procs.tcl 17 Nov 2008 13:35:03 -0000 1.8 @@ -1,7 +1,7 @@ ad_library { IMS Content Packaging functions - for Blackboard 6 + for Blackboard 6 @creation-date 2003-10-13 @author Ernie Ghiglione (ErnieG@mm.st) @@ -40,12 +40,12 @@ @author Ernie Ghiglione (ErnieG@mm.st) } { - return [file exists $tmp_dir/.bb-package-info] + return [file exists $tmp_dir/.bb-package-info] } ad_proc -public lors::imscp::bb6::getItems { - {tree} + {tree} {parent ""} } { Extracts data from Items @@ -59,36 +59,32 @@ set itemx [$tree child all item] if { ![empty_string_p $itemx] } { - if {[empty_string_p $parent]} { set parent 0 } - set it_list "" + set it_list "" foreach itemx [$tree child all item] { - set cc "" - #{$parent}" + # gets item identifier set cc "[lors::imsmd::getAtt $itemx identifier]" # gets item identifierref set cc [concat $cc "[lors::imsmd::getAtt $itemx identifierref]"] - # gets xml node - set cc [concat $cc $itemx] + # gets xml node + set cc [concat $cc $itemx] + set it_list [concat $it_list [list $cc]] - set it_list [concat $it_list [list $cc]] - set itemxx [$itemx child all item] if { ![empty_string_p $itemxx] } { - set it_list [concat $it_list [getItems $itemx]] - } + set it_list [concat $it_list [getItems $itemx]] + } set items [concat $items $cc] } } return $it_list - #$items } @@ -109,6 +105,7 @@ } } + ad_proc -public lors::imscp::bb6::getDescription { -node:required } { @@ -138,7 +135,8 @@ if {![empty_string_p dates_node]} { set created [$dates_node child all CREATED] set updated [$dates_node child all UPDATED] - return [list [lors::imsmd::getAtt $created value] [lors::imsmd::getAtt $updated value]] + return [list \ + [lors::imsmd::getAtt $created value] [lors::imsmd::getAtt $updated value]] } else { return "" } @@ -163,7 +161,6 @@ } else { return "" } - } else { return "" } @@ -176,7 +173,7 @@ @option name Name of the attribute to get @option node XML node - + @author Ernie Ghiglione (ErnieG@mm.st) } { set navigation [$node child all [string toupper NAVIGATION]] @@ -212,7 +209,7 @@ # coursetoc set coursetoc [$doc documentElement] - set list_items [list] + set list_items [list] # gets coursetoc elements and values lappend list_items {id} [lors::imsmd::getAtt $coursetoc id] @@ -231,7 +228,6 @@ # return list return $list_items - } @@ -245,11 +241,11 @@ } { # open xml file set doc [dom parse [::tDOM::xmlReadFile $file]] + # content set content [$doc documentElement] + set list_items [list] - set list_items [list] - # gets content elements and values lappend list_items {id} [lors::imsmd::getAtt $content id] lappend list_items {TITLE} [lors::imsmd::getAtt [$content getElementsByTagName TITLE] value] @@ -275,28 +271,22 @@ set files [list] foreach file [[$content selectNodes /CONTENT/FILES] childNodes] { + set file_list [list] + lappend file_list {file_id} [lors::imsmd::getAtt $file id] + lappend file_list {NAME} [lors::imsmd::getElement [$file getElementsByTagName NAME]] + lappend file_list {FILEACTION} [lors::imsmd::getAtt [$file getElementsByTagName FILEACTION] value] + lappend file_list {LINKNAME} [lors::imsmd::getAtt [$file getElementsByTagName LINKNAME] value] + lappend file_list {SIZE} [lors::imsmd::getAtt [$file getElementsByTagName SIZE] value] + lappend file_list {CREATED} [lors::imsmd::getAtt [$file getElementsByTagName CREATED] value] + lappend file_list {UPDATED} [lors::imsmd::getAtt [$file getElementsByTagName UPDATED] value] - set file_list [list] - lappend file_list {file_id} [lors::imsmd::getAtt $file id] - lappend file_list {NAME} [lors::imsmd::getElement [$file getElementsByTagName NAME]] - lappend file_list {FILEACTION} [lors::imsmd::getAtt [$file getElementsByTagName FILEACTION] value] - lappend file_list {LINKNAME} [lors::imsmd::getAtt [$file getElementsByTagName LINKNAME] value] - lappend file_list {SIZE} [lors::imsmd::getAtt [$file getElementsByTagName SIZE] value] - lappend file_list {CREATED} [lors::imsmd::getAtt [$file getElementsByTagName CREATED] value] - lappend file_list {UPDATED} [lors::imsmd::getAtt [$file getElementsByTagName UPDATED] value] + foreach registryentry [[$file getElementsByTagName REGISTRY] childNodes] { + if {[$registryentry getAttribute key] == "entry_point"} { + lappend file_list {REGISTRY_ENTRY_POINT} [lors::imsmd::getAtt $registryentry value] + } + } - foreach registryentry [[$file getElementsByTagName REGISTRY] childNodes] { - - if {[$registryentry getAttribute key] == "entry_point"} { - - lappend file_list {REGISTRY_ENTRY_POINT} [lors::imsmd::getAtt $registryentry value] - - } - - } - - lappend files $file_list - + lappend files $file_list } lappend list_items {FILES} $files @@ -325,27 +315,26 @@ # check if directory exists if { ![file exists $dirname] } { - # create dir - file mkdir $dirname + file mkdir $dirname } # transforms text into html if {[lors::imscp::bb6::looks_like_html_p -text $txt]} { -# set txt [ad_text_to_html -includes_html $txt] + # set txt [ad_text_to_html -includes_html $txt] } else { - set txt [ad_text_to_html -includes_html $txt] -# set txt [ad_html_text_convert -from "text/plain" -to "text/html" $txt] + set txt [ad_text_to_html -includes_html $txt] + # set txt [ad_html_text_convert -from "text/plain" -to "text/html" $txt] } # saves it on a new html file set f_handler [open $filename w+] fconfigure $f_handler -encoding utf-8 - puts -nonewline $f_handler " \ $txt \" + puts -nonewline $f_handler " \ $txt \" close $f_handler # returns what is is an href for resources return $filename - } @@ -360,10 +349,12 @@ @author Ernie Ghiglione (ErnieG@mm.st) } { - if { [regexp -nocase {

} $text] || [regexp -nocase {
} $text] || [regexp -nocase {} $text] || [regexp -nocase {} $text] } { - return 1 + if { [regexp -nocase {

} $text] || [regexp -nocase {
} $text] || \ + [regexp -nocase {} $text] || \ + [regexp -nocase {} $text] } { + return 1 } else { - return 0 + return 0 } } @@ -381,9 +372,8 @@ set doc [dom parse [::tDOM::xmlReadFile $file]] # content set announcement [$doc documentElement] + set list_items [list] - set list_items [list] - # gets announcement elements and values lappend list_items {id} [lors::imsmd::getAtt $announcement id] lappend list_items {TITLE} [lors::imsmd::getAtt [$announcement getElementsByTagName TITLE] value] @@ -416,12 +406,10 @@ } { if {[lsearch -exact [lindex $resource_files 0] PACKAGE] == -1} { - return 0 + return 0 } else { - return 1 + return 1 } - - } ad_proc -private lors::imscp::bb6::process_package { @@ -431,7 +419,7 @@ -resource:required -entry_point:required } { - Process the BB Packages: makes it IMS CP + Process the BB Packages: makes it IMS CP compliant (rather than BB's weird interpretation of IMS CP). @@ -450,78 +438,71 @@ # file name), then collect all the # unzipped file and # add them as files in the resource. - + # additionally, we need to change the # resource to # point out to the entry_point on the # package. - set path "$tmp_dir/$res_identifier" - + ns_log Notice "WE GOTTA PACKAGE PATH: $path FILE: $zipfile" - + ## ## Unzip file and add those to the # resource and point the href to # the entry_point ## - + # Now we unzip the package file # into the exact directory where # the resource - set errp [catch { exec unzip -jd $path $path/$zipfile } errmsg] - + # catch any errors if {$errp} { - ns_log Notice "lors::imscp::bb6::extract_html doc_bb: package zip error ($errmsg)" - return -code error "lors::imscp::bb6::extract_html doc_bb: package zip error ($errmsg)" + ns_log Notice "lors::imscp::bb6::extract_html doc_bb: package zip error ($errmsg)" + return -code error "lors::imscp::bb6::extract_html doc_bb: package zip error ($errmsg)" } - + # Now we delete the zip file as we # don't need it any more - exec rm -fr $path/$zipfile - + # Also we remove the actual file # children for the resource as # they exist in the BB XMl file as # we are going to replace them now - $resource removeChild [$resource firstChild] - + # now we get all the files in the - # directory. - + # directory. set all_packaged_files [lors::imscp::dir_walk $path] - + foreach filex $all_packaged_files { - # we add the files to the - # resource - - # create the file XML node - set file_doc [dom createDocument file] - set file_nodex [$file_doc documentElement] - - # we get rid of the /tmp/xyz - # part of the path and only - # put the relative href - - regsub $tmp_dir $filex {} filex - - # set the href to the file node - $file_nodex setAttribute href $filex - - # append the file node as child - # for the resource - - $resource appendChild $file_nodex - + # we add the files to the + # resource + + # create the file XML node + set file_doc [dom createDocument file] + set file_nodex [$file_doc documentElement] + + # we get rid of the /tmp/xyz + # part of the path and only + # put the relative href + regsub $tmp_dir $filex {} filex + + # set the href to the file node + $file_nodex setAttribute href $filex + + # append the file node as child + # for the resource + + $resource appendChild $file_nodex } - + # now let's reference the resource # to point to the BB entry_point - + $resource setAttribute href "/$res_identifier/$entry_point" } @@ -541,7 +522,7 @@ # content set forum [$doc documentElement] - set list_items [list] + set list_items [list] # gets forum elements and values lappend list_items {id} [lors::imsmd::getAtt $forum id] @@ -556,7 +537,6 @@ # return list return $list_items - } @@ -566,11 +546,11 @@ -tmp_dir:required -file:required } { - Blackboard 6 by default does not create manifest metadata. - However, it does have some sort of metadata in the res00001.dat + Blackboard 6 by default does not create manifest metadata. + However, it does have some sort of metadata in the res00001.dat file, so we extract that information and create a LOM metadata record - @param tmp_dir temporary directory where the imsmanifest.xml is located. + @param tmp_dir temporary directory where the imsmanifest.xml is located. @option file filename @author Ernie Ghiglione (ErnieG@mm.st) } { @@ -584,53 +564,50 @@ # Check if it has a metadata node for the manifest # If it doesn't let's create one with the description we get from # res00001.dat - + set metadata [$manifest child all metadata] if {[empty_string_p $metadata]} { - - set filex res00001.dat - set docx [dom parse [::tDOM::xmlReadFile $tmp_dir/$filex]] - # gets BB's course info - set course [$docx documentElement] - - set title [lors::imsmd::getAtt [$course selectNodes /COURSE/TITLE] value] - set description [lindex [lors::imsmd::getElement [$course selectNodes /COURSE/DESCRIPTION]] 0] - $docx delete + set filex res00001.dat + set docx [dom parse [::tDOM::xmlReadFile $tmp_dir/$filex]] + # gets BB's course info + set course [$docx documentElement] - # create a metadata node - set docx [dom createDocument metadata] - set metadata [$docx documentElement] + set title [lors::imsmd::getAtt [$course selectNodes /COURSE/TITLE] value] + set description [lindex [lors::imsmd::getElement [$course selectNodes /COURSE/DESCRIPTION]] 0] + $docx delete - set general_node [lors::imsmd::create::lom_general \ - -owner $metadata \ - -title [list en $title] \ - -description [list en $description] \ - ] + # create a metadata node + set docx [dom createDocument metadata] + set metadata [$docx documentElement] - set lom_node [lors::imsmd::create::lom \ - -owner $metadata \ - -general $general_node \ - ] - set md [lors::imsmd::create::md -owner $metadata \ - -schema "IMS Content" \ - -schemaversion "1.1.2" \ - -lom $lom_node \ - ] + set general_node [lors::imsmd::create::lom_general \ + -owner $metadata \ + -title [list en $title] \ + -description [list en $description]] - $manifest insertBefore $md [$manifest child all organizations] + set lom_node [lors::imsmd::create::lom \ + -owner $metadata \ + -general $general_node] - set f_handler [open /tmp/imsmanifest.xml w+] - puts -nonewline $f_handler [$manifest asXML -indent 1 -escapeNonASCII] - close $f_handler - - $doc delete + set md [lors::imsmd::create::md \ + -owner $metadata \ + -schema "IMS Content" \ + -schemaversion "1.1.2" \ + -lom $lom_node] - file copy -force /tmp/imsmanifest.xml $tmp_dir/$file + $manifest insertBefore $md [$manifest child all organizations] + set f_handler [open /tmp/imsmanifest.xml w+] + puts -nonewline $f_handler [$manifest asXML -indent 1 -escapeNonASCII] + close $f_handler + + $doc delete + + file copy -force /tmp/imsmanifest.xml $tmp_dir/$file } } @@ -640,9 +617,9 @@ -tmp_dir:required -file:required } { - This function cleans up a lot of the unused and empty ims_items that Blackboard has when exporting their courses. Apparently Blackboard exports all their application information and sets the availability of these applications within the .dat files. This function looks into some of the Blackboard specific resource types and based on their availability or data, we adapt it to a purer IMS CP standards. + This function cleans up a lot of the unused and empty ims_items that Blackboard has when exporting their courses. Apparently Blackboard exports all their application information and sets the availability of these applications within the .dat files. This function looks into some of the Blackboard specific resource types and based on their availability or data, we adapt it to a purer IMS CP standards. - @param tmp_dir temporary directory where the imsmanifest.xml is located. + @param tmp_dir temporary directory where the imsmanifest.xml is located. @option file filename @author Ernie Ghiglione (ErnieG@mm.st) } { @@ -657,18 +634,14 @@ set organizations [$manifest child all organizations] if { ![empty_string_p $organizations] } { - - set num_organizations [$organizations child all organization] + set num_organizations [$organizations child all organization] - set items 0 + set items 0 - set items_list [list] - foreach organization $num_organizations { - - set items_list [lors::imscp::bb6::getItems $organization] - - } - + set items_list [list] + foreach organization $num_organizations { + set items_list [lors::imscp::bb6::getItems $organization] + } } @@ -677,190 +650,162 @@ # Complain if there's no resources if {[empty_string_p $resources]} { - ad_return_complaint 1 "The package you are trying to upload doesn't have resources. Please check the $file and try again" - ad_script_abort - } + ad_return_complaint 1 "The package you are trying to upload + doesn't have resources. Please check the $file and try again" + ad_script_abort + } set resourcex [$resources child all resource] - set resources_list [list] foreach resource $resourcex { + set res_identifier [lors::imsmd::getResource -node $resource -att identifier] + set res_type [lors::imsmd::getResource -node $resource -att type] + set res_href [lors::imsmd::getResource -node $resource -att href] + set res_dependencies [lors::imsmd::getResource -node $resource -att dependencies] + set res_hasmetadata [lors::imsmd::hasMetadata $resource] + set res_files [lors::imsmd::getResource -node $resource -att files] + set res_scormtype [lors::imsmd::getAtt $resource adlcp:scormtype] - set res_identifier [lors::imsmd::getResource -node $resource -att identifier] - set res_type [lors::imsmd::getResource -node $resource -att type] - set res_href [lors::imsmd::getResource -node $resource -att href] - set res_dependencies [lors::imsmd::getResource -node $resource -att dependencies] - set res_hasmetadata [lors::imsmd::hasMetadata $resource] - set res_files [lors::imsmd::getResource -node $resource -att files] - set res_scormtype [lors::imsmd::getAtt $resource adlcp:scormtype] - - switch $res_type { - - "course/x-bb-coursetoc" { - - set file [lors::imsmd::getAtt $resource bb:file] - array set ernie [lors::imscp::bb6::get_coursetoc -file $tmp_dir/$file] + switch $res_type { + "course/x-bb-coursetoc" { + set file [lors::imsmd::getAtt $resource bb:file] + array set ernie [lors::imscp::bb6::get_coursetoc -file $tmp_dir/$file] + set enabled_p $ernie(ISENABLED) - set enabled_p $ernie(ISENABLED) - - } - - "resource/x-bb-document" { + } "resource/x-bb-document" { + set file [lors::imsmd::getAtt $resource bb:file] + array set ernie [lors::imscp::bb6::get_bb_doc -file $tmp_dir/$file] + set enabled_p $ernie(ISAVAILABLE) - set file [lors::imsmd::getAtt $resource bb:file] - array set ernie [lors::imscp::bb6::get_bb_doc -file $tmp_dir/$file] + } default { + set enabled_p "no_type" + } + } - set enabled_p $ernie(ISAVAILABLE) - - } - - default { - set enabled_p "no_type" - } - - - - } - - lappend resources_list [list [lors::imsmd::getAtt $resource identifier] [lors::imsmd::getAtt $resource type] $resource $enabled_p] - + lappend resources_list [list [lors::imsmd::getAtt $resource identifier] \ + [lors::imsmd::getAtt $resource type] $resource $enabled_p] } # ns_log Notice "HERE IS THE LIST OF ITEMS: ([llength $items_list]) $items_list \nResource list ([llength $resources_list]) $resources_list" - + ns_log Notice "\n\n" foreach item $items_list { - - ns_log Notice "\n------Begin-----\nItem identifier [lindex $item 0]\n" - ns_log Notice "Item resource reference: [lindex $item 1]\n" + ns_log Notice "\n------Begin-----\nItem identifier [lindex $item 0]\n" + ns_log Notice "Item resource reference: [lindex $item 1]\n" + ns_log Notice "Lsearch result: [lsearch -regexp $resources_list [lindex $item 1]]\n" - ns_log Notice "Lsearch result: [lsearch -regexp $resources_list [lindex $item 1]]\n" + set resource [lindex $resources_list [lsearch -regexp $resources_list [lindex $item 1]]] - set resource [lindex $resources_list [lsearch -regexp $resources_list [lindex $item 1]]] + ns_log Notice "is Resource enabled?: [lindex $resource 3]\n" - ns_log Notice "is Resource enabled?: [lindex $resource 3]\n" + if {[lindex $resource 3] == "false"} { + switch [lindex $resource 1] { + "resource/x-bb-document" { + # if the resource is a document and also is false or + # disable, that means (according to my interpretation + # of Blackboard XML files, that these documents are + # only to be rendered to admins, but not to students. - if {[lindex $resource 3] == "false"} { + # Since IMS doesn't have anything to support + # permissions within their own items, then we added an + # attribute as an extension: dotLRN:permission. - switch [lindex $resource 1] { + ns_log Notice "\tDocument Type\n" + ns_log Notice "\tAdding attribute to [lindex $item 2] \n" + [lindex $item 2] setAttributeNS dotLRN dotLRN:permission admin + } "course/x-bb-coursetoc" { - "resource/x-bb-document" { - # if the resource is a document and also is false or - # disable, that means (according to my interpretation - # of Blackboard XML files, that these documents are - # only to be rendered to admins, but not to students. + ns_log Notice "\Coursetoc Type \n" + ns_log Notice "\tAdding attribute to [lindex $item 2] \n" + if {![empty_string_p [[lindex $item 2] child all item]]} { + [lindex $item 2] setAttributeNS dotLRN dotLRN:permission admin + } else { + ns_log Notice "\tdeleting [lindex $item 0] - [lindex $item 2] as it is false\n" + ns_log Notice "\tdeleting node [lindex $item 2] \n" - # Since IMS doesn't have anything to support - # permissions within their own items, then we added an - # attribute as an extension: dotLRN:permission. + [lindex $item 2] delete - ns_log Notice "\tDocument Type\n" - ns_log Notice "\tAdding attribute to [lindex $item 2] \n" - [lindex $item 2] setAttributeNS dotLRN dotLRN:permission admin - } + ns_log Notice "\tand its corresponding resource [lindex $resource 2]\n" + ns_log Notice "\tDeleting files from FS: [lors::imsmd::getResource -node [lindex $resource 2] -att files]\n" + ns_log Notice "\tDeleting dat file: [lors::imsmd::getAtt [lindex $resource 2] bb:file]\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt [lindex $resource 2] bb:file] + [lindex $resource 2] delete + } - "course/x-bb-coursetoc" { + } default { - ns_log Notice "\Coursetoc Type \n" - ns_log Notice "\tAdding attribute to [lindex $item 2] \n" - if {![empty_string_p [[lindex $item 2] child all item]]} { - [lindex $item 2] setAttributeNS dotLRN dotLRN:permission admin - } else { - ns_log Notice "\tdeleting [lindex $item 0] - [lindex $item 2] as it is false\n" - ns_log Notice "\tdeleting node [lindex $item 2] \n" - - [lindex $item 2] delete - - ns_log Notice "\tand its corresponding resource [lindex $resource 2]\n" - ns_log Notice "\tDeleting files from FS: [lors::imsmd::getResource -node [lindex $resource 2] -att files]\n" - ns_log Notice "\tDeleting dat file: [lors::imsmd::getAtt [lindex $resource 2] bb:file]\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt [lindex $resource 2] bb:file] - [lindex $resource 2] delete - } + if {[empty_string_p [[lindex $item 2] child all item]]} { + ns_log Notice "\tdeleting [lindex $item 0] - [lindex $item 2] as it is false\n" + ns_log Notice "\tdeleting node [lindex $item 2] \n" - } + [lindex $item 2] delete - default { + ns_log Notice "\tand its corresponding resource [lindex $resource 2]\n" + ns_log Notice "\tDeleting files from FS: [lors::imsmd::getResource -node [lindex $resource 2] -att files]\n" + ns_log Notice "\tDeleting dat file: [lors::imsmd::getAtt [lindex $resource 2] bb:file]\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt [lindex $resource 2] bb:file] + [lindex $resource 2] delete + } + } + } + } else { + ns_log Notice "\tResource is enabled... therefore nothing to do here\n" + switch [lindex $resource 1] { + "course/x-bb-coursetoc" { + ns_log Notice "Item: [lindex $item 0] [lindex $item 1] + ([lindex $item 2]) has [llength [[lindex $item 2] + child all item]]] items" + if {[empty_string_p [[lindex $item 2] child all item]]} { + # this corsetoc item is childless, + # therefore we nuke it (as it is an + # empty folder + ns_log Notice "Therefore [lindex $item 0] [lindex $item 1] ([lindex $item 2]) we delete it.." - if {[empty_string_p [[lindex $item 2] child all item]]} { - ns_log Notice "\tdeleting [lindex $item 0] - [lindex $item 2] as it is false\n" - ns_log Notice "\tdeleting node [lindex $item 2] \n" - - [lindex $item 2] delete - - ns_log Notice "\tand its corresponding resource [lindex $resource 2]\n" - ns_log Notice "\tDeleting files from FS: [lors::imsmd::getResource -node [lindex $resource 2] -att files]\n" - ns_log Notice "\tDeleting dat file: [lors::imsmd::getAtt [lindex $resource 2] bb:file]\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt [lindex $resource 2] bb:file] - [lindex $resource 2] delete - } + [lindex $item 2] delete - } - } - - } else { - ns_log Notice "\tResource is enabled... therefore nothing to do here\n" - switch [lindex $resource 1] { + ns_log Notice "\tand its corresponding resource [lindex $resource 2]\n" + ns_log Notice "\tDeleting files from FS: [lors::imsmd::getResource -node + [lindex $resource 2] -att files]\n" + ns_log Notice "\tDeleting dat file: [lors::imsmd::getAtt [lindex $resource 2] bb:file]\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt [lindex $resource 2] bb:file] + [lindex $resource 2] delete + } - "course/x-bb-coursetoc" { - - ns_log Notice "Item: [lindex $item 0] [lindex $item 1] ([lindex $item 2]) has [llength [[lindex $item 2] child all item]]] items" - if {[empty_string_p [[lindex $item 2] child all item]]} { - # this corsetoc item is childless, - # therefore we nuke it (as it is an - # empty folder - ns_log Notice "Therefore [lindex $item 0] [lindex $item 1] ([lindex $item 2]) we delete it.." - - [lindex $item 2] delete - - ns_log Notice "\tand its corresponding resource [lindex $resource 2]\n" - ns_log Notice "\tDeleting files from FS: [lors::imsmd::getResource -node [lindex $resource 2] -att files]\n" - ns_log Notice "\tDeleting dat file: [lors::imsmd::getAtt [lindex $resource 2] bb:file]\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt [lindex $resource 2] bb:file] - [lindex $resource 2] delete - } - - } - default { - # this item has good content - ns_log Notice "\t we can't delete [lindex $item 0] - [lindex $item 2] as it has child items -- [[lindex $item 2] child all item]\n" - - } - - } - - } - ns_log Notice "------End------\n" - + } default { + # this item has good content + ns_log Notice "\t we can't delete [lindex $item 0] - [lindex $item 2] as it has child items -- [[lindex $item 2] child all item]\n" + } + } + } + ns_log Notice "------End------\n" } set f_handler [open /tmp/imsmanifest.xml w+] puts -nonewline $f_handler [$manifest asXML -indent 1 -escapeNonASCII] close $f_handler - + $doc delete - + file copy -force /tmp/imsmanifest.xml $tmp_dir/imsmanifest.xml - } ad_proc -public lors::imscp::bb6::extract_html { -tmp_dir:required -file:required } { - This is a massive function that does a lot of things. + This is a massive function that does a lot of things. It extracts the HTML from Blackboard's proprietary .dat files - Cleans ups a lot of unused application data and resources. + Cleans ups a lot of unused application data and resources. (this should be customizable in a different functions) Now it also handles BB packages (a weird way of zipping files) that suppose to be declared in the imsmanifest, but of course they are not. Thanks Blackboard for making interoperability possible (NOT!) - @param tmp_dir temporary directory where the imsmanifest.xml is located. + @param tmp_dir temporary directory where the imsmanifest.xml is located. @option file filename @author Ernie Ghiglione (ErnieG@mm.st) } { @@ -870,344 +815,306 @@ # gets the manifest tree set manifest [$doc documentElement] - # Gets the organizations set organizations [$manifest child all organizations] - if { ![empty_string_p $organizations] } { + set num_organizations [$organizations child all organization] + set items 0 - set num_organizations [$organizations child all organization] - - set items 0 - - foreach organization $num_organizations { - - set items [expr $items + [lors::imscp::countItems $organization]] - - } - + foreach organization $num_organizations { + set items [expr $items + [lors::imscp::countItems $organization]] + } } # gets the resources set resources [$manifest child all resources] # Complain if there's no resources if {[empty_string_p $resources]} { - ad_return_complaint 1 "The package you are trying to upload doesn't have resources. Please check the $file and try again" - ad_script_abort - } + ad_return_complaint 1 "The package you are trying to upload doesn't + have resources. Please check the $file and try again" + ad_script_abort + } set resourcex [$resources child all resource] foreach resource $resourcex { - set res_identifier [lors::imsmd::getResource -node $resource -att identifier] - set res_type [lors::imsmd::getResource -node $resource -att type] - set res_href [lors::imsmd::getResource -node $resource -att href] - set res_dependencies [lors::imsmd::getResource -node $resource -att dependencies] - set res_hasmetadata [lors::imsmd::hasMetadata $resource] - set res_files [lors::imsmd::getResource -node $resource -att files] - set res_scormtype [lors::imsmd::getAtt $resource adlcp:scormtype] + set res_identifier [lors::imsmd::getResource \ + -node $resource \ + -att identifier] + set res_type [lors::imsmd::getResource -node $resource -att type] + set res_href [lors::imsmd::getResource -node $resource -att href] + set res_dependencies [lors::imsmd::getResource \ + -node $resource \ + -att dependencies] + set res_hasmetadata [lors::imsmd::hasMetadata $resource] + set res_files [lors::imsmd::getResource -node $resource -att files] + set res_scormtype [lors::imsmd::getAtt $resource adlcp:scormtype] - switch $res_type { + switch $res_type { + "course/x-bb-coursetoc" { - "course/x-bb-coursetoc" { + set file [lors::imsmd::getAtt $resource bb:file] + array set resourcext [lors::imscp::bb6::get_coursetoc -file $tmp_dir/$file] - set file [lors::imsmd::getAtt $resource bb:file] - array set resourcext [lors::imscp::bb6::get_coursetoc -file $tmp_dir/$file] + ns_log Notice "\n\n$file ($resourcext(ISENABLED)) $resourcext(LABEL)\n" - ns_log Notice "\n\n$file ($resourcext(ISENABLED)) $resourcext(LABEL)\n" + # set content folder to be the appropiate IMS webcontent + # type instead of "couse/x-bb-coursetoc" BB's propietary type + $resource removeAttribute type + $resource removeAttribute bb:file + $resource removeAttribute bb:title + $resource setAttribute type webcontent - # set content folder to be the appropiate IMS webcontent - # type instead of "couse/x-bb-coursetoc" BB's propietary type - $resource removeAttribute type - $resource removeAttribute bb:file - $resource removeAttribute bb:title - $resource setAttribute type webcontent + } "resource/x-bb-document" { + set file [lors::imsmd::getAtt $resource bb:file] + array set resourcext [lors::imscp::bb6::get_bb_doc -file $tmp_dir/$file] - } - "resource/x-bb-document" { + ns_log Notice "\n--resource document Begin\n" + ns_log Notice " ISFOLDER: $resourcext(ISFOLDER)" + ns_log Notice "\n\n $file [llength $resourcext(FILES)] $resourcext(FILES)" - set file [lors::imsmd::getAtt $resource bb:file] - array set resourcext [lors::imscp::bb6::get_bb_doc -file $tmp_dir/$file] + # change the resources type from proprietary BB's + # "resource/x-bb-document" to webcontent as defined by IMS + $resource removeAttribute type + $resource removeAttribute bb:title + $resource setAttribute type webcontent - ns_log Notice "\n--resource document Begin\n" - ns_log Notice " ISFOLDER: $resourcext(ISFOLDER)" - ns_log Notice "\n\n $file [llength $resourcext(FILES)] $resourcext(FILES)" - - # change the resources type from proprietary BB's - # "resource/x-bb-document" to webcontent as defined by IMS - $resource removeAttribute type - $resource removeAttribute bb:title - $resource setAttribute type webcontent - - if { $resourcext(ISFOLDER) == "true" } { + if { $resourcext(ISFOLDER) == "true" } { + if {$resourcext(TEXT) != "{}"} { + ns_log Notice "\n it has text" + set folder [lors::imsmd::getAtt $resource identifier] + set filename $resourcext(id).html + set res_href [lors::imscp::bb6::txt_to_html \ + -txt [lindex $resourcext(TEXT) 0] \ + -filename $tmp_dir/$folder/$filename] - if {$resourcext(TEXT) != "{}"} { + regsub $tmp_dir $res_href {} res_href + ns_log Notice " \n And we set up the attribute to: href $res_href\n" - ns_log Notice "\n it has text" - set folder [lors::imsmd::getAtt $resource identifier] + $resource setAttribute href $res_href - set filename $resourcext(id).html + } else { + ns_log Notice "\n doesn't have text\n" + } - set res_href [lors::imscp::bb6::txt_to_html -txt [lindex $resourcext(TEXT) 0] -filename $tmp_dir/$folder/$filename] + } else { + # if it ain't a folder - regsub $tmp_dir $res_href {} res_href - ns_log Notice " \n And we set up the attribute to: href $res_href\n" + # check if the content of TEXT tag is HTML or not + # If it is, then we need to assume that TEXT has + # embedded HTML code that references to the files + # under the FILES tag (this could be a bit tricky, but + # there's not much we can do for now) - $resource setAttribute href $res_href + ns_log Notice "\nlist of files: [lindex $resourcext(FILES) 0]\n" - } else { - ns_log Notice "\n doesn't have text\n" + if { $resourcext(TYPE) == "H" } { + if {$resourcext(TEXT) != "{}"} { + ns_log Notice "\n it has text" + set content [lindex $resourcext(TEXT) 0] - - } - - } else { - # if it ain't a folder + # we transform the text into HTML if required + if {![lors::imscp::bb6::looks_like_html_p \ + -text [lindex $resourcext(TEXT) 0]]} { + set content [ad_html_text_convert \ + -from "text/plain" \ + -to "text/html" [lindex $resourcext(TEXT) 0]] + } else { + set content [lindex $resourcext(TEXT) 0] + } - # check if the content of TEXT tag is HTML or not - # If it is, then we need to assume that TEXT has - # embedded HTML code that references to the files - # under the FILES tag (this could be a bit tricky, but - # there's not much we can do for now) + set folder [lors::imsmd::getAtt $resource identifier] - ns_log Notice "\nlist of files: [lindex $resourcext(FILES) 0]\n" - - if { $resourcext(TYPE) == "H" } { + set filename $resourcext(id).html + set counter 0 + set files_lister "" + set has_packages [lors::imscp::bb6::has_packages \ + -resource_files $resourcext(FILES)] - if {$resourcext(TEXT) != "{}"} { - - ns_log Notice "\n it has text" - set content [lindex $resourcext(TEXT) 0] + foreach file $resourcext(FILES) { + ns_log Notice "\n\t We gotta file: $file\n " - # we transform the text into HTML if required - if {![lors::imscp::bb6::looks_like_html_p -text [lindex $resourcext(TEXT) 0]]} { - set content [ad_html_text_convert -from "text/plain" -to "text/html" [lindex $resourcext(TEXT) 0]] - } else { - set content [lindex $resourcext(TEXT) 0] - } + # We need to find out whether this + # file is a package or just a file to + # be added to the end of the HTML + # TODO - set folder [lors::imsmd::getAtt $resource identifier] + # Here's where we handle BB packages. BB packages + # are a painful thing that BB engineers use to + # complicate the life of other people + # -like me- to get access to their + # files - set filename $resourcext(id).html + # A BB package is a zip file that + # contains a bunch of other file + # within it. There's really *no* + # reason for the BB people to package + # them, but I guess it's just to make + # it more difficult for to inter + # exchange content with other systems. - set counter 0 - set files_lister "" - set has_packages [lors::imscp::bb6::has_packages -resource_files $resourcext(FILES)] + # Does it have a package? - foreach file $resourcext(FILES) { - ns_log Notice "\n\t We gotta file: $file\n " + if {$has_packages != 0} { + lors::imscp::bb6::process_package \ + -tmp_dir $tmp_dir \ + -zipfile [lindex $file 3] \ + -res_identifier $res_identifier \ + -resource $resource \ + -entry_point [lindex $file 15] - # We need to find out whether this - # file is a package or just a file to - # be added to the end of the HTML - # TODO + } else { - # Here's where we handle BB packages. BB packages - # are a painful thing that BB engineers use to - # complicate the life of other people - # -like me- to get access to their - # files + # if this is not a package, then + # it checks whether the files are + # referenced in the content and + # otherwise it adds them - # A BB package is a zip file that - # contains a bunch of other file - # within it. There's really *no* - # reason for the BB people to package - # them, but I guess it's just to make - # it more difficult for to inter - # exchange content with other systems. + if {[regexp [lindex $file 3] $content]} { + ns_log Notice "\t [lindex $file 7]: [lindex $file 3] is referenced\n" + } else { + if {$counter == 0} { + append files_lister "

Files:

\n\n" + regsub -nocase "" $content $files_lister content + } - lors::imscp::bb6::process_package -tmp_dir $tmp_dir \ - -zipfile [lindex $file 3] \ - -res_identifier $res_identifier \ - -resource $resource \ - -entry_point [lindex $file 15] + set res_href [lors::imscp::bb6::txt_to_html \ + -txt $content -filename $tmp_dir/$folder/$filename] - } else { - - # if this is not a package, then - # it checks whether the files are - # referenced in the content and - # otherwise it adds them + regsub $tmp_dir $res_href {} res_href + ns_log Notice " \n And we set up the attribute to: href $res_href\n" - if {[regexp [lindex $file 3] $content]} { - ns_log Notice "\t [lindex $file 7]: [lindex $file 3] is referenced\n" - } else { - if {$counter == 0} { - - append files_lister "

Files:

\n\n" - regsub -nocase "" $content $files_lister content - } + if {$file_href(FILEACTION) == "PACKAGE"} { + lors::imscp::bb6::process_package \ + -tmp_dir $tmp_dir \ + -zipfile $file_href(NAME) \ + -res_identifier $res_identifier \ + -resource $resource \ + -entry_point $file_href(REGISTRY_ENTRY_POINT) + } else { + ns_log Notice "\n the HREF for this file should + be /$res_identifier/$file_href(NAME)\n" + set res_href "/$res_identifier/$file_href(NAME)" + $resource setAttribute href $res_href + } + } else { + set folder [lors::imsmd::getAtt $resource identifier] + set filename $resourcext(id).html - set res_href [lors::imscp::bb6::txt_to_html -txt $content -filename $tmp_dir/$folder/$filename] + # in the case this is type "S" and also + # the resource CONTENTHANDLER = + # resource/x-bb-externallink and + # RENDERTYPE = URL, then we add this link + # to the TEXT (if any) as part of the + # content - regsub $tmp_dir $res_href {} res_href - ns_log Notice " \n And we set up the attribute to: href $res_href\n" + set partial_content [lindex $resourcext(TEXT) 0] - $resource setAttribute href $res_href - } - } + if {$resourcext(CONTENTHANDLER) == "resource/x-bb-externallink" \ + && $resourcext(RENDERTYPE) == "URL"} { + append partial_content "\n

\n\t$resourcext(TITLE)\n

" + } - } else { + set res_href [lors::imscp::bb6::txt_to_html \ + -txt $partial_content \ + -filename $tmp_dir/$folder/$filename] + regsub $tmp_dir $res_href {} res_href + ns_log Notice " \n And we set up the attribute to: href $res_href\n" - if {![empty_string_p [lindex $resourcext(FILES) 0]]} { + $resource setAttribute href $res_href + } + } + } - array set file_href [lindex $resourcext(FILES) 0] + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + ns_log Notice "\n--DELETED FILE $tmp_dir/[lors::imsmd::getAtt $resource bb:file]--\n" + $resource removeAttribute bb:file + ns_log Notice "\n--resource document END--\n" - if {$file_href(FILEACTION) == "PACKAGE"} { - lors::imscp::bb6::process_package -tmp_dir $tmp_dir \ - -zipfile $file_href(NAME) \ - -res_identifier $res_identifier \ - -resource $resource \ - -entry_point $file_href(REGISTRY_ENTRY_POINT) - } else { - - ns_log Notice "\n the HREF for this file should be /$res_identifier/$file_href(NAME)\n" - - set res_href "/$res_identifier/$file_href(NAME)" - - $resource setAttribute href $res_href - } + } "assessment/x-bb-qti-survey" { + # if it's not content, then we delete the resource and the + # dat file. + ns_log Notice "\n--resource qti-survey: [lors::imsmd::getAtt $resource bb:file] deleted\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + ns_log Notice "Deleting qti-survey resource $resource" + $resource delete - } else { - set folder [lors::imsmd::getAtt $resource identifier] + } "resource/x-bb-announcement" { + ns_log Notice "\n--resource ANNOUNCEMENT \n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete + ns_log Notice "Deleting Announcement resource $resource" + ns_log Notice "Deleting Announcement resource $resource" - set filename $resourcext(id).html + } "resource/x-bb-discussionboard" { + ns_log Notice "\n--resource FORUM POSTING \n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete - # in the case this is type "S" and also - # the resource CONTENTHANDLER = - # resource/x-bb-externallink and - # RENDERTYPE = URL, then we add this link - # to the TEXT (if any) as part of the - # content + } "course/x-bb-gradebook" { + ns_log Notice "\n--resource gradebook: [lors::imsmd::getAtt $resource bb:file] deleted\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete - set partial_content [lindex $resourcext(TEXT) 0] + } "course/x-bb-coursenavsetting" { + ns_log Notice "\n--resource navsettings: [lors::imsmd::getAtt $resource bb:file] deleted\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete + } "course/x-bb-courseappsetting" { + ns_log Notice "\n--resource courseappsetting: [lors::imsmd::getAtt $resource bb:file] deleted\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete - if {$resourcext(CONTENTHANDLER) == "resource/x-bb-externallink" && $resourcext(RENDERTYPE) == "URL"} { - append partial_content "\n

\n\t$resourcext(TITLE)\n

" - } + } "course/x-bb-coursesetting" { + ns_log Notice "\n--resource coursesetting: [lors::imsmd::getAtt $resource bb:file] deleted\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete - set res_href [lors::imscp::bb6::txt_to_html -txt $partial_content \ - -filename $tmp_dir/$folder/$filename] + } "resource/x-bb-conference" { - regsub $tmp_dir $res_href {} res_href - ns_log Notice " \n And we set up the attribute to: href $res_href\n" + ns_log Notice "\n--resource conference: [lors::imsmd::getAtt $resource bb:file] deleted\n" + exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] + $resource delete - $resource setAttribute href $res_href - - - } - } - } - - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - ns_log Notice "\n--DELETED FILE $tmp_dir/[lors::imsmd::getAtt $resource bb:file]--\n" - $resource removeAttribute bb:file - ns_log Notice "\n--resource document END--\n" - - } - "assessment/x-bb-qti-survey" { - - # if it's not content, then we delete the resource and the - # dat file. - ns_log Notice "\n--resource qti-survey: [lors::imsmd::getAtt $resource bb:file] deleted\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - ns_log Notice "Deleting qti-survey resource $resource" - $resource delete - - - } - "resource/x-bb-announcement" { - ns_log Notice "\n--resource ANNOUNCEMENT \n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - ns_log Notice "Deleting Announcement resource $resource" - ns_log Notice "Deleting Announcement resource $resource" - - } - "resource/x-bb-discussionboard" { - ns_log Notice "\n--resource FORUM POSTING \n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - - } - "course/x-bb-gradebook" { - - ns_log Notice "\n--resource gradebook: [lors::imsmd::getAtt $resource bb:file] deleted\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - - } - "course/x-bb-coursenavsetting" { - - ns_log Notice "\n--resource navsettings: [lors::imsmd::getAtt $resource bb:file] deleted\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - - } - "course/x-bb-courseappsetting" { - - ns_log Notice "\n--resource courseappsetting: [lors::imsmd::getAtt $resource bb:file] deleted\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - - } - "course/x-bb-coursesetting" { - - ns_log Notice "\n--resource coursesetting: [lors::imsmd::getAtt $resource bb:file] deleted\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - - } - "resource/x-bb-conference" { - - ns_log Notice "\n--resource conference: [lors::imsmd::getAtt $resource bb:file] deleted\n" - exec rm -fr $tmp_dir/[lors::imsmd::getAtt $resource bb:file] - $resource delete - - } - } - - + } + } } - set f_handler [open /tmp/imsmanifest.xml w+] puts -nonewline $f_handler [$manifest asXML -indent 1 -escapeNonASCII] close $f_handler $doc delete - file copy -force /tmp/imsmanifest.xml $tmp_dir/imsmanifest.xml - } - - -### End Cleanup Functions \ No newline at end of file