]> git.mjollnir.org Git - moodle.git/commitdiff
Added Blackboard restore using XSLT. Works with BB 5.5 and BB 6.0.
authormoodler <moodler>
Tue, 8 Feb 2005 07:19:49 +0000 (07:19 +0000)
committermoodler <moodler>
Tue, 8 Feb 2005 07:19:49 +0000 (07:19 +0000)
Completely untested by me but it LOOKS like it should work.  It's quite
standalone, and is basically a single function call during the restore
precheck which looks in the backup to see if it's a BB file, then
converts it using XSLT.

Apart from a little tidyup and renaming, I added a check so that it
should just silently fail if XSLT functions aren't available

Many thanks to Ziba Scott <ziba@linuxbox.com> who wrote it!

backup/bb/README.txt [new file with mode: 0644]
backup/bb/bb5.5_to_moodle.xsl [new file with mode: 0644]
backup/bb/bb6_to_moodle.xsl [new file with mode: 0644]
backup/bb/restore_bb.php [new file with mode: 0644]
backup/restore.php
backup/restorelib.php

diff --git a/backup/bb/README.txt b/backup/bb/README.txt
new file mode 100644 (file)
index 0000000..e19a3c9
--- /dev/null
@@ -0,0 +1,73 @@
+Ziba Scott <ziba@linuxbox.com> 11/19/04
+
+This is a beta demonstration of a utility to convert Blackboard
+Course export zip files into Moodle course export zip files. It
+has been successfully tested with Blackboard 5.5 and
+Moodle 1.4.1 and Moodle CVS. There is minimal Blackboard 6 support.
+It will convert:
+
+    * Course Name/Title
+    * Forum Topics
+    * Course Documents
+    * Assignments 
+    * External Links 
+
+The current status of this project is
+exploration/proof-of-concept. We have successfully converted
+basic Blackboard course information as well as course documents
+and forum topics using the XSLT methods described above. 
+
+AUTOMATED OPERATION:
+  
+  REQUIREMENTS FOR WEB INTERFACE:
+    *Moodle 1.4.1 or greater
+    *PHP compiled with --enable-xslt  --with-xslt-sablot options
+    (Check php.net for instructions on enabling xslt for your platform)
+  
+  INSTALLATION:
+    *Unpack this file into the "backup" directory
+
+
+
+MANUAL OPERATION:
+
+  REQUIREMENTS:
+    
+    *An XSLT 1.0 processor (like Sablotron)
+    *A zipping utility
+
+  REQUIREMENTS FOR WEB INTERFACE:
+
+    *Linux/Unix
+    *PHP compiled with --enable-xslt  --with-xslt-sablot options.
+    *Apache with write access to /tmp
+    *A commandline zipping utility
+    
+  COMMAND LINE INSTRUCTIONS:
+
+    1) Download and uncompress the Blackboard export into a directory.
+    
+    2) Copy bb2moodle.xslt into the Blackboard course directory.
+    
+    3) Run your XSLT processor on imsmanifest.xml with bb2moodle.xslt
+       as the input and moodle.xml as the output.  If you are using
+       Sablotron on linux, this command will look like this:
+          sabcmd bb2moodle.xslt imsmanifest.xml > moodle.xml 
+          
+    4) Create a moodle zip file with this structure:
+       moodle.xml
+       user_files/
+       course_files/
+       
+    5) Copy every subdirectory and its contents from the Blackboard
+       export directory into the course_files directory.  This does
+       not include the Blackboard XML files, only the course
+       documents.  Your moodle zip file will now look similar to
+       this:
+       moodle.xml
+       user_files/
+       course_files/res0009/myfile.doc
+       course_files/res0010/myotherfile.doc
+       course_files/res0010/mypicture.jpg
+
+    6) Upload and restore your moodle zip file
diff --git a/backup/bb/bb5.5_to_moodle.xsl b/backup/bb/bb5.5_to_moodle.xsl
new file mode 100644 (file)
index 0000000..bf87485
--- /dev/null
@@ -0,0 +1,737 @@
+<?xml version='1.0'?>
+<xsl:stylesheet version="1.0"
+     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:template match="/">
+  <MOODLE_BACKUP>
+   <INFO>
+    <NAME>backup-from-blackboard.zip</NAME>
+    <MOODLE_VERSION>2004083100</MOODLE_VERSION>
+    <MOODLE_RELEASE>1.4</MOODLE_RELEASE>
+    <BACKUP_VERSION>2004083100</BACKUP_VERSION>
+    <BACKUP_RELEASE>1.4</BACKUP_RELEASE>
+    <DATE>1094240862</DATE>
+    <ORIGINAL_WWWROOT>INSERT URL HERE</ORIGINAL_WWWROOT>
+    <DETAILS>
+      <MOD>
+        <NAME>assignment</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>chat</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>choice</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>forum</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>glossary</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>journal</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>label</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>lesson</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>quiz</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>resource</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>scorm</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>survey</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>wiki</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>workshop</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <USERS>course</USERS>
+      <LOGS>false</LOGS>
+      <USERFILES>true</USERFILES>
+      <COURSEFILES>true</COURSEFILES>
+    </DETAILS>
+  </INFO>
+  <COURSE>
+    <!-- Get course specific information -->
+    <xsl:apply-templates select="document('res00001.dat')//COURSE"/>
+
+    
+  <SECTIONS>
+    <!-- Create a title section -->
+    <xsl:for-each select="document('res00001.dat')" >
+      <xsl:call-template name="title_section" />
+    </xsl:for-each>
+
+
+    <!-- Create a topic for each top level Bb item and add section modules ONE folder deep -->
+    <xsl:for-each select="manifest/organizations/tableofcontents/item">
+      <xsl:variable name="section_number" select="position()"/>
+      <xsl:call-template name="sections">
+            <xsl:with-param name="section_number" select="$section_number"/>
+            <xsl:with-param name="recurse" >false</xsl:with-param>
+          </xsl:call-template>
+    </xsl:for-each>
+
+    <!-- Create a topic for each second level Bb item which is a folder, recursively make section modules  -->
+    <xsl:for-each select="manifest/organizations/tableofcontents/item/item">
+      <xsl:sort order="descending" select="document(concat(@identifierref,'.dat'))/CONTENT/FLAGS/ISFOLDER/@value"/>
+      <xsl:if test="document(concat(@identifierref,'.dat'))/CONTENT/FLAGS/ISFOLDER/@value = 'true'">
+        <xsl:variable name="prev_sections" select="count(/manifest/organizations/tableofcontents/item)"/>
+        <xsl:variable name="section_number" select="position()+$prev_sections"/>
+        <xsl:call-template name="sections">
+              <xsl:with-param name="section_number" select="$section_number"/>
+              <xsl:with-param name="recurse" >true</xsl:with-param>
+        </xsl:call-template>
+      </xsl:if>
+    </xsl:for-each>
+  </SECTIONS>
+    
+  <MODULES>
+    <xsl:call-template name="modules" />
+  </MODULES>
+    
+  </COURSE>
+  </MOODLE_BACKUP>
+</xsl:template>
+
+<xsl:template match="COURSE">
+      <HEADER>
+      <ID>2</ID>
+      <CATEGORY>
+        <ID></ID>
+        <NAME><xsl:value-of select="CATEGORIES/CATEGORY/@value"/></NAME>
+      </CATEGORY>
+      <PASSWORD></PASSWORD>
+      <IDNUMBER>4</IDNUMBER>
+      <FORMAT>topics</FORMAT>
+      <SHOWGRADES>1</SHOWGRADES>
+      <BLOCKINFO>participants,activity_modules,search_forums,admin,course_list:news_items,calendar_upcoming,recent_activity</BLOCKINFO>
+      <NEWSITEMS>5</NEWSITEMS>
+      <TEACHER>Teacher</TEACHER>
+      <TEACHERS>Teachers</TEACHERS>
+      <STUDENT>Student</STUDENT>
+      <STUDENTS>Students</STUDENTS>
+      <GUEST>0</GUEST>
+      <STARTDATE>1094270400</STARTDATE>
+      <ENROLPERIOD>0</ENROLPERIOD>
+      <NUMSECTIONS>10</NUMSECTIONS>
+      <MAXBYTES>2097152</MAXBYTES>
+      <SHOWREPORTS>0</SHOWREPORTS>
+      <GROUPMODE>0</GROUPMODE>
+      <GROUPMODEFORCE>0</GROUPMODEFORCE>
+      <LANG></LANG>
+      <COST></COST>
+      <MARKER>0</MARKER>
+      <VISIBLE>1</VISIBLE>
+      <HIDDENSECTIONS>0</HIDDENSECTIONS>
+      <TIMECREATED>1094240775</TIMECREATED>
+      <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+      <SUMMARY><xsl:value-of select="DESCRIPTION"/></SUMMARY>
+      <SHORTNAME><xsl:value-of select="COURSEID/@value"/></SHORTNAME>
+      <FULLNAME><xsl:value-of select="TITLE/@value"/></FULLNAME>
+      </HEADER>
+</xsl:template>
+
+<!-- ############# Sections ############# -->
+
+<xsl:template name="title_section" match="resource">
+    <SECTION>
+      <ID>0</ID>
+      <NUMBER>0</NUMBER>
+      <SUMMARY>&lt;div style="text-align: center;"&gt;&lt;font size="5" style="font-family: arial,helvetica,sans-serif;"&gt;<xsl:value-of select="COURSE/TITLE/@value"/>&lt;/font&gt;&lt;/div&gt;
+        <xsl:value-of select="COURSE/DESCRIPTION"/>
+      </SUMMARY>
+      <VISIBLE>1</VISIBLE>
+      <MODS>
+          <xsl:call-template name="news_forum_section_mod" >
+            <xsl:with-param name="mod_number">1</xsl:with-param>
+          </xsl:call-template>
+      </MODS>
+    </SECTION>
+</xsl:template>
+
+<xsl:template name="sections" match="resource">
+    <xsl:param name="section_number">1. </xsl:param>
+    <xsl:param name="recurse"/>
+    <SECTION>
+      <ID><xsl:value-of select="$section_number"/></ID>
+      <NUMBER><xsl:value-of select="$section_number"/></NUMBER>
+      <SUMMARY>&lt;span style="font-weight: bold;"&gt;<xsl:value-of select="@title"/>&lt;/span&gt;</SUMMARY>
+      <VISIBLE>1</VISIBLE>
+      <MODS>
+        
+        <xsl:if test="$recurse = 'true'">
+          <xsl:variable name="mod_number" select="substring-after(@identifierref,'res')"/>
+          <xsl:call-template name="item_recurse_files" >
+                <xsl:with-param name="mod_number" select="$mod_number"/>
+                <xsl:with-param name="indent" >0</xsl:with-param>
+                <xsl:with-param name="recurse" select="$recurse" />
+          </xsl:call-template>
+        
+        </xsl:if>
+
+        <xsl:if test="$recurse = 'false'">
+        <xsl:for-each select="item">
+          <xsl:variable name="mod_number" select="substring-after(@identifierref,'res')"/>
+            <xsl:if test="document(concat(@identifierref,'.dat'))/CONTENT/FLAGS/ISFOLDER/@value != 'true' or document(concat(@identifierref,'.dat'))/EXTERNALLINK/DESCRIPTION/FLAGS/ISHTML/@value ='true'">
+            <!-- Create one section-mod -->
+            <xsl:for-each select="document(concat(@identifierref,'.dat'))">
+              <xsl:call-template name="section_mod">
+                    <xsl:with-param name="mod_number" select="$mod_number"/>
+                    <xsl:with-param name="indent" select="0"/>
+              </xsl:call-template>
+            </xsl:for-each>
+            
+           </xsl:if>
+       </xsl:for-each> 
+        </xsl:if>
+  
+
+      </MODS>
+    </SECTION>
+  </xsl:template>
+
+<xsl:template name="item_recurse_files">
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+   <xsl:param name="recurse"/>
+
+   
+    <!-- Create one section-mod -->
+    <xsl:for-each select="document(concat(@identifierref,'.dat'))">
+      <xsl:call-template name="section_mod">
+          <xsl:with-param name="mod_number" select="$mod_number"/>
+          <xsl:with-param name="indent" select="$indent"/>
+      </xsl:call-template>
+    </xsl:for-each>
+    
+    <!-- Depth first recursion to preserve order -->
+    <xsl:for-each select="item">
+      <xsl:variable name="m_number" select="substring-after(@identifierref,'res')"/>
+      <xsl:call-template name="item_recurse_files" >
+            <xsl:with-param name="mod_number" select="$m_number"/>
+            <xsl:with-param name="indent" select="$indent + 1"/>
+      </xsl:call-template>
+    </xsl:for-each>
+    
+</xsl:template>
+
+
+<!-- Determines the type of section mod entry and calls the appropriate creation template -->
+<xsl:template name="section_mod" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="contenttype" />
+   <xsl:param name="indent">1. </xsl:param>
+
+  <!-- Every file will have a label module describing it -->
+  <xsl:choose>
+      <!-- Detected one or more files -->
+      <xsl:when test="CONTENT/FILES/FILEREF/RELFILE/@value != ''">
+        
+        <!-- Create a label -->
+        <xsl:call-template name="section_mod_generic">
+          <xsl:with-param name="mod_number" ><xsl:value-of select="$mod_number"/></xsl:with-param>
+          <xsl:with-param name="indent" ><xsl:value-of select="$indent"/></xsl:with-param>
+              <xsl:with-param name="type" >label</xsl:with-param>
+        </xsl:call-template>
+        
+        <!-- Create a resource for each file -->
+        <xsl:for-each select="CONTENT/FILES/FILEREF">
+        <xsl:call-template name="section_mod_generic">
+          <xsl:with-param name="mod_number" ><xsl:value-of select="$mod_number"/>0<xsl:value-of select="position()"/></xsl:with-param>
+              <xsl:with-param name="indent" select="$indent + 1"/>
+              <xsl:with-param name="type" >resource</xsl:with-param>
+        </xsl:call-template>
+      </xsl:for-each>
+        
+      </xsl:when>
+
+
+      <!-- Detected a folder -->
+      <xsl:when test="CONTENT/FLAGS/ISFOLDER/@value = 'true'">
+        <!-- Create a label -->
+        <xsl:call-template name="section_mod_generic">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+              <xsl:with-param name="type" >label</xsl:with-param>
+        </xsl:call-template>
+      </xsl:when>
+
+      <!-- Detected text -->
+      <xsl:when test="CONTENT/MAINDATA/FLAGS/ISHTML/@value = 'true'">
+        <!-- Create a resource -->
+        <xsl:call-template name="section_mod_generic">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+              <xsl:with-param name="type" >resource</xsl:with-param>
+        </xsl:call-template>
+      </xsl:when>
+
+      <!-- Detected external link -->
+      <xsl:when test="EXTERNALLINK/TITLE/@value != '' ">
+         <!-- Create a label -->
+        <xsl:call-template name="section_mod_generic">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+              <xsl:with-param name="type" >label</xsl:with-param>
+        </xsl:call-template>
+
+        <!-- Create a resource -->
+        <xsl:call-template name="section_mod_generic">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+              <xsl:with-param name="type" >resource</xsl:with-param>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+      </xsl:otherwise>
+
+  </xsl:choose>
+
+
+</xsl:template>
+
+<!-- ############# Section Modules ############# -->
+<!-- Creates one section module entry. 
+     Works for types: label, resource (text), resource (externallink)
+-->
+<xsl:template name="section_mod_generic" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+   <xsl:param name="type"/>
+  
+  <MOD>
+    <ID><xsl:if test="$type = 'label'">1</xsl:if><xsl:value-of select="$mod_number"/>0</ID>
+         <ZIBA_NAME>
+      <xsl:value-of select="CONTENT/TITLE"/>
+      <xsl:value-of select="EXTERNALLINK/TITLE/@value"/>
+         </ZIBA_NAME>
+    <TYPE><xsl:value-of select="$type"/></TYPE>
+    <INSTANCE><xsl:value-of select="$mod_number"/></INSTANCE>
+    <ADDED>1094240775</ADDED>
+    <DELETED>0</DELETED>
+    <SCORE>0</SCORE>
+    <INDENT><xsl:value-of select="$indent"/></INDENT>
+    <VISIBLE>1</VISIBLE>
+    <GROUPMODE>0</GROUPMODE>
+  </MOD>
+   
+</xsl:template>
+
+<!-- ############# Modules ############# -->
+<!-- Creates a module-label entry -->
+<xsl:template name="module_label" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <LABELFOUND></LABELFOUND>
+    <MODTYPE>label</MODTYPE>
+    <NAME>
+      <!-- for CONTENT text -->
+      <xsl:value-of select="TITLE"/>
+      <!-- for EXTERNALLINK text -->
+      <xsl:value-of select="TITLE/@value"/>
+    </NAME>
+    <CONTENT>
+      &lt;span style="font-style: italic;"&gt;
+      <!-- for CONTENT text -->
+      <xsl:value-of select="TITLE"/>
+      <!-- for EXTERNALLINK text -->
+      <xsl:value-of select="TITLE/@value"/>
+      :&lt;/span&gt;
+      <!-- for CONTENT text -->
+      <xsl:value-of select="MAINDATA/TEXT"/> 
+      <!-- for EXTERNALLINK text -->
+      <xsl:value-of select="DESCRIPTION/TEXT"/> 
+    </CONTENT>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+   
+<!-- Creates one module-file entry -->
+<xsl:template name="module_file" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>resource</MODTYPE>
+    <NAME>
+      <!-- <xsl:value-of select="FILES/FILEREF/RELFILE/@value"/> -->
+     <xsl:value-of select="RELFILE/@value"/>
+    </NAME>
+    <TYPE>file</TYPE>
+    <REFERENCE>
+      <!-- <xsl:value-of select="FILES/FILEREF/CONTENTID/@value"/>/<xsl:value-of select="FILES/FILEREF/RELFILE/@value"/> -->
+      <xsl:value-of select="CONTENTID/@value"/>/<xsl:value-of select="RELFILE/@value"/>
+    </REFERENCE>
+    <SUMMARY>
+      summary broken
+     <xsl:value-of select="MAINDATA/TEXT"/>
+    </SUMMARY>
+    <ALLTEXT></ALLTEXT>
+    <POPUP></POPUP>
+    <OPTIONS>frame</OPTIONS>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+
+<!-- Creates one module-text entry -->
+<xsl:template name="module_text" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>resource</MODTYPE>
+    <NAME>
+      <xsl:value-of select="TITLE"/>
+      <!-- For announcements -->
+      <xsl:value-of select="TITLE/@value"/>
+    </NAME>
+    <TYPE>text</TYPE>
+    <REFERENCE></REFERENCE>
+    <SUMMARY>
+      <xsl:value-of select="TITLE"/>
+      <!-- For announcements -->
+      <xsl:value-of select="TITLE/@value"/>
+    </SUMMARY>
+    <ALLTEXT>
+      <xsl:value-of select="MAINDATA/TEXT"/>
+      <!-- For announcements -->
+      <xsl:value-of select="DESCRIPTION/TEXT"/>
+    </ALLTEXT>
+    <POPUP></POPUP>
+    <OPTIONS></OPTIONS>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+
+<!-- Creates one module-link entry -->
+<xsl:template name="module_link" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>resource</MODTYPE>
+    <NAME>
+      <xsl:value-of select="URL/@value"/>
+    </NAME>
+    <TYPE>file</TYPE>
+    <REFERENCE>
+      <xsl:value-of select="URL/@value"/>
+    </REFERENCE>
+    <SUMMARY>
+      <xsl:value-of select="TITLE/@value"/>&lt;br/&gt;
+      <xsl:value-of select="URL/@value"/>
+    </SUMMARY>
+    <ALLTEXT>
+      <xsl:value-of select="DESCRIPTION/TEXT"/>
+    </ALLTEXT>
+    <POPUP></POPUP>
+    <OPTIONS>frame</OPTIONS>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+
+<!-- ############# Modules Decisions ############# -->
+
+<!-- Creates all module entries -->
+<xsl:template name="modules" match="resource">
+  <!-- Create the News Forum Module -->
+       <xsl:call-template name="news_forum_mod">
+         <xsl:with-param name="mod_number" >1</xsl:with-param>
+       </xsl:call-template>
+  <!-- Create all other modules -->
+  <xsl:for-each select="//resource">
+    <xsl:variable name="mod_number" select="substring-after(@identifier,'res')"/>
+    <xsl:for-each select="document(concat('',@file))">
+          <xsl:apply-templates select="//FORUM">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+          </xsl:apply-templates>
+          <xsl:apply-templates select="//CONTENT">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+          </xsl:apply-templates>
+          <xsl:apply-templates select="//EXTERNALLINK">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+          </xsl:apply-templates>
+    </xsl:for-each>
+  </xsl:for-each>
+</xsl:template>
+  
+
+<!-- Create an EXTERNALLINK module entry -->
+<xsl:template match="EXTERNALLINK">
+   <xsl:param name="mod_number">1. </xsl:param>
+       <!-- Every link module will have a label module describing it -->
+       <xsl:call-template name="module_label">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+       
+       <xsl:call-template name="module_link">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+
+</xsl:template>
+
+<!-- Create a CONTENT module entry -->
+<xsl:template match="CONTENT">
+   <xsl:param name="mod_number">1. </xsl:param>
+
+  <xsl:choose>
+      <!-- Detected a file -->
+      <xsl:when test="FILES/FILEREF/RELFILE/@value != ''">
+
+       <!-- Every file module will have a label module describing it -->
+       <xsl:call-template name="module_label">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+       
+      <xsl:for-each select="FILES/FILEREF">
+       <xsl:call-template name="module_file">
+        <xsl:with-param name="mod_number" ><xsl:value-of select="$mod_number"/>0<xsl:value-of select="position()"/></xsl:with-param>
+       </xsl:call-template>
+      </xsl:for-each>
+
+      </xsl:when>
+      
+      <!-- Detected a folder -->
+      <xsl:when test="FLAGS/ISFOLDER/@value = 'true'">
+        
+        <xsl:call-template name="module_label">
+          <xsl:with-param name="mod_number" select="$mod_number"/>
+        </xsl:call-template>
+        
+      </xsl:when>
+      
+      <!-- Detected text -->
+      <xsl:when test="MAINDATA/FLAGS/ISHTML/@value = 'true'">
+        
+       <xsl:call-template name="module_text">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+      
+      </xsl:when>
+    
+      <xsl:otherwise>
+    <UNKNOWN>
+      <xsl:value-of select="TITLE"/>
+    </UNKNOWN>
+        </xsl:otherwise>
+  </xsl:choose>
+
+</xsl:template>
+<!-- ############# Forum conversion ################# -->
+
+<xsl:template match="FORUM">
+   <xsl:param name="mod_number">1. </xsl:param>
+       <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+               <MODTYPE>forum</MODTYPE>
+               <TYPE>general</TYPE>
+         <NAME>
+      <xsl:value-of select="TITLE/@value"/>
+         </NAME>
+         <INTRO>
+      <xsl:value-of select="DESCRIPTION/TEXT"/> 
+         </INTRO>
+         <OPEN>2</OPEN>
+         <ASSESSED>0</ASSESSED>
+         <ASSESSPUBLIC>0</ASSESSPUBLIC>
+         <ASSESSTIMESTART>0</ASSESSTIMESTART>
+         <ASSESSTIMEFINISH>0</ASSESSTIMEFINISH>
+         <MAXBYTES>0</MAXBYTES>
+         <SCALE>0</SCALE>
+         <FORCESUBSCRIBE>0</FORCESUBSCRIBE>
+         <RSSTYPE>0</RSSTYPE>
+         <RSSARTICLES>0</RSSARTICLES>
+         <TIMEMODIFIED></TIMEMODIFIED>
+    <!--
+    <DISCUSSIONS>
+      <xsl:for-each select="MESSAGETHREADS/MSG">
+      <xsl:variable name="discussion_id" select="position()"/>
+      <DISCUSSION>
+        <ID>
+          <xsl:value-of select="$mod_number"/>0<xsl:value-of select="$discussion_id"/>
+        </ID>
+        <NAME>
+          <xsl:value-of select="TITLE/@value"/> 
+        </NAME>
+        <FIRSTPOST>2</FIRSTPOST>
+        <USERID>1</USERID>
+        <GROUPID>-1</GROUPID>
+        <ASSESSED>1</ASSESSED>
+        <TIMEMODIFIED>1094748430</TIMEMODIFIED>
+        <USERMODIFIED>1</USERMODIFIED>
+        <POSTS>
+          <xsl:call-template name="MSG">
+            <xsl:with-param name="parent" select="0"/>
+            <xsl:with-param name="post_id">
+            <xsl:value-of select="$mod_number"/>0<xsl:value-of select="$discussion_id"/>0<xsl:value-of select="position()"/>
+            </xsl:with-param>
+          </xsl:call-template>
+        </POSTS>
+      </DISCUSSION>
+      </xsl:for-each>
+    </DISCUSSIONS>
+      -->
+       </MOD>
+</xsl:template>
+
+<xsl:template name="MSG" match="MSG">
+    <xsl:param name="parent" select="1"/>
+    <xsl:param name="post_id" select="1"/>
+    <POST>
+      <ID><xsl:value-of select="$post_id"/></ID>
+      <PARENT> <xsl:value-of select="$parent"/></PARENT>
+      <USERID>1</USERID>
+      <CREATED>1094748430</CREATED>
+      <MODIFIED>1094748430</MODIFIED>
+      <MAILED>1</MAILED>
+      <SUBJECT><xsl:value-of select="TITLE/@value"/></SUBJECT>
+      <MESSAGE><xsl:value-of select="MESSAGETEXT"/></MESSAGE>
+      <FORMAT>1</FORMAT>
+      <ATTACHMENT></ATTACHMENT>
+      <TOTALSCORE>0</TOTALSCORE>
+    </POST>
+
+      <xsl:for-each select="MSG">
+          <xsl:call-template name="MSG">
+            <xsl:with-param name="parent" select="$post_id"/>
+            <xsl:with-param name="post_id">
+            <xsl:value-of select="$post_id"/>0<xsl:value-of select="position()"/>
+            </xsl:with-param>
+          </xsl:call-template>
+      </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="news_forum_section_mod" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID>1</ID>
+         <ZIBA_NAME>
+      News forum
+         </ZIBA_NAME>
+    <TYPE>news</TYPE>
+    <INSTANCE>1</INSTANCE>
+    <ADDED>1094240775</ADDED>
+    <DELETED>0</DELETED>
+    <SCORE>0</SCORE>
+    <INDENT>0</INDENT>
+    <VISIBLE>1</VISIBLE>
+    <GROUPMODE>0</GROUPMODE>
+  </MOD>
+</xsl:template>
+
+<xsl:template name="news_forum_mod" >
+   <xsl:param name="mod_number">1. </xsl:param>
+       <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+               <MODTYPE>forum</MODTYPE>
+               <TYPE>news</TYPE>
+         <NAME>News forum</NAME>
+         <INTRO>General news and announcements</INTRO>
+         <OPEN>2</OPEN>
+         <ASSESSED>0</ASSESSED>
+         <ASSESSPUBLIC>0</ASSESSPUBLIC>
+         <ASSESSTIMESTART>0</ASSESSTIMESTART>
+         <ASSESSTIMEFINISH>0</ASSESSTIMEFINISH>
+         <MAXBYTES>0</MAXBYTES>
+         <SCALE>0</SCALE>
+         <FORCESUBSCRIBE>0</FORCESUBSCRIBE>
+         <RSSTYPE>0</RSSTYPE>
+         <RSSARTICLES>0</RSSARTICLES>
+         <TIMEMODIFIED></TIMEMODIFIED>
+    <DISCUSSIONS>
+      <xsl:for-each select="//resource">
+        <xsl:variable name="m_number" select="substring-after(@identifier,'res')"/>
+        <xsl:variable name="discussion_id" select="position()"/>
+        <xsl:for-each select="document(concat('',@file))">
+         <xsl:if test="//ANNOUNCEMENT/TITLE/@value != ''">
+          <xsl:call-template name="ANNOUNCEMENT">
+            <xsl:with-param name="discussion_id" select="$discussion_id"/>
+          </xsl:call-template>
+        </xsl:if>
+         </xsl:for-each>
+       </xsl:for-each>
+
+     </DISCUSSIONS>
+       </MOD>
+</xsl:template>
+
+<!-- Create an ANNOUNCEMENT forum entry -->
+<xsl:template name="ANNOUNCEMENT" >
+  <xsl:param name="discussion_id">1. </xsl:param>
+      <DISCUSSION>
+        <ID>
+          <xsl:value-of select="$discussion_id"/>
+        </ID>
+        <NAME><xsl:value-of select="//ANNOUNCEMENT/TITLE/@value"/></NAME>
+        <FIRSTPOST><xsl:value-of select="$discussion_id"/></FIRSTPOST>
+        <USERID>1</USERID>
+        <GROUPID>-1</GROUPID>
+        <ASSESSED>1</ASSESSED>
+        <TIMEMODIFIED>1094748430</TIMEMODIFIED>
+        <USERMODIFIED>1</USERMODIFIED>
+        <POSTS>
+          <POST>
+            <ID><xsl:value-of select="$discussion_id"/></ID>
+            <PARENT>0</PARENT>
+            <USERID>1</USERID>
+            <CREATED>1094748430</CREATED>
+            <MODIFIED>1094748430</MODIFIED>
+            <MAILED>1</MAILED>
+            <SUBJECT><xsl:value-of select="//ANNOUNCEMENT/TITLE/@value"/></SUBJECT>
+            <MESSAGE><xsl:value-of select="//ANNOUNCEMENT/DESCRIPTION/TEXT"/></MESSAGE>
+            <FORMAT>1</FORMAT>
+            <ATTACHMENT></ATTACHMENT>
+            <TOTALSCORE>0</TOTALSCORE>
+          </POST>
+        </POSTS>
+      </DISCUSSION>
+
+          <!--
+          <xsl:call-template name="MSG">
+            <xsl:with-param name="parent" select="0"/>
+            <xsl:with-param name="post_id">
+            <xsl:value-of select="$mod_number"/>0<xsl:value-of select="$discussion_id"/>0<xsl:value-of select="position()"/>
+            </xsl:with-param>
+          </xsl:call-template>
+          -->
+</xsl:template>
+
+
+</xsl:stylesheet>
+
diff --git a/backup/bb/bb6_to_moodle.xsl b/backup/bb/bb6_to_moodle.xsl
new file mode 100644 (file)
index 0000000..1bbabb7
--- /dev/null
@@ -0,0 +1,690 @@
+<?xml version='1.0'?>
+<xsl:stylesheet version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+>
+<xsl:template match="/">
+  <MOODLE_BACKUP>
+   <INFO>
+    <NAME>backup-from-blackboard.zip</NAME>
+    <MOODLE_VERSION>2004083100</MOODLE_VERSION>
+    <MOODLE_RELEASE>1.4</MOODLE_RELEASE>
+    <BACKUP_VERSION>2004083100</BACKUP_VERSION>
+    <BACKUP_RELEASE>1.4</BACKUP_RELEASE>
+    <DATE>1094240862</DATE>
+    <ORIGINAL_WWWROOT>INSERT URL HERE</ORIGINAL_WWWROOT>
+    <DETAILS>
+      <MOD>
+        <NAME>assignment</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>chat</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>choice</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>forum</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>glossary</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>journal</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>label</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>lesson</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>quiz</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>resource</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>scorm</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>survey</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>wiki</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <MOD>
+        <NAME>workshop</NAME>
+        <INCLUDED>true</INCLUDED>
+        <USERINFO>true</USERINFO>
+      </MOD>
+      <USERS>course</USERS>
+      <LOGS>false</LOGS>
+      <USERFILES>true</USERFILES>
+      <COURSEFILES>true</COURSEFILES>
+    </DETAILS>
+  </INFO>
+  <COURSE>
+    <!-- Get course specific information -->
+    <xsl:apply-templates select="document('res00001.dat')//COURSE"/>
+
+    <xsl:call-template name="modules" />
+    
+  <SECTIONS>
+    <!-- Create a title section -->
+    <xsl:for-each select="document('res00001.dat')" >
+      <xsl:call-template name="title_section" />
+    </xsl:for-each>
+
+
+    <!-- Create a topic for each top level Bb item and add section modules ONE folder deep -->
+    <xsl:for-each select="manifest/organizations/organization/item">
+      <xsl:variable name="section_number" select="position()"/>
+      <xsl:call-template name="sections">
+            <xsl:with-param name="section_number" select="$section_number"/>
+            <xsl:with-param name="recurse" >false</xsl:with-param>
+          </xsl:call-template>
+    </xsl:for-each>
+
+    <!-- Create a topic for each second level Bb item which is a folder, recursively make section modules  -->
+    <xsl:for-each select="manifest/organizations/organization/item/item">
+      <xsl:sort order="descending" select="document(concat(@identifierref,'.dat'))/CONTENT/FLAGS/ISFOLDER/@value"/>
+      <xsl:if test="document(concat(@identifierref,'.dat'))/CONTENT/FLAGS/ISFOLDER/@value = 'true'">
+        <xsl:variable name="prev_sections" select="count(/manifest/organizations/tableofcontents/item)"/>
+        <xsl:variable name="section_number" select="position()+$prev_sections"/>
+        <xsl:call-template name="sections">
+              <xsl:with-param name="section_number" select="$section_number"/>
+              <xsl:with-param name="recurse" >true</xsl:with-param>
+        </xsl:call-template>
+      </xsl:if>
+    </xsl:for-each>
+  </SECTIONS>
+    
+  </COURSE>
+  </MOODLE_BACKUP>
+</xsl:template>
+
+<xsl:template match="COURSE">
+      <HEADER>
+      <ID>2</ID>
+      <CATEGORY>
+        <ID></ID>
+        <NAME><xsl:value-of select="CATEGORIES/CATEGORY/@value"/></NAME>
+      </CATEGORY>
+      <PASSWORD></PASSWORD>
+      <IDNUMBER>4</IDNUMBER>
+      <FORMAT>topics</FORMAT>
+      <SHOWGRADES>1</SHOWGRADES>
+      <BLOCKINFO>participants,activity_modules,search_forums,admin,course_list:news_items,calendar_upcoming,recent_activity</BLOCKINFO>
+      <NEWSITEMS>5</NEWSITEMS>
+      <TEACHER>Teacher</TEACHER>
+      <TEACHERS>Teachers</TEACHERS>
+      <STUDENT>Student</STUDENT>
+      <STUDENTS>Students</STUDENTS>
+      <GUEST>0</GUEST>
+      <STARTDATE>1094270400</STARTDATE>
+      <ENROLPERIOD>0</ENROLPERIOD>
+      <NUMSECTIONS>10</NUMSECTIONS>
+      <MAXBYTES>2097152</MAXBYTES>
+      <SHOWREPORTS>0</SHOWREPORTS>
+      <GROUPMODE>0</GROUPMODE>
+      <GROUPMODEFORCE>0</GROUPMODEFORCE>
+      <LANG></LANG>
+      <COST></COST>
+      <MARKER>0</MARKER>
+      <VISIBLE>1</VISIBLE>
+      <HIDDENSECTIONS>0</HIDDENSECTIONS>
+      <TIMECREATED>1094240775</TIMECREATED>
+      <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+      <SUMMARY><xsl:value-of select="DESCRIPTION"/></SUMMARY>
+      <SHORTNAME><xsl:value-of select="COURSEID/@value"/></SHORTNAME>
+      <FULLNAME><xsl:value-of select="TITLE/@value"/></FULLNAME>
+      </HEADER>
+</xsl:template>
+
+<xsl:template name="title_section" match="resource">
+    <SECTION>
+      <ID>0</ID>
+      <NUMBER>0</NUMBER>
+      <SUMMARY>&lt;div style="text-align: center;"&gt;&lt;font size="5" style="font-family: arial,helvetica,sans-serif;"&gt;<xsl:value-of select="COURSE/TITLE/@value"/>&lt;/font&gt;&lt;/div&gt;
+        <xsl:value-of select="COURSE/DESCRIPTION"/>
+      </SUMMARY>
+      <VISIBLE>1</VISIBLE>
+      <MODS>
+      </MODS>
+    </SECTION>
+</xsl:template>
+
+<xsl:template name="sections" match="resource">
+    <xsl:param name="section_number">1. </xsl:param>
+    <xsl:param name="recurse"/>
+    <SECTION>
+      <ID><xsl:value-of select="$section_number"/></ID>
+      <NUMBER><xsl:value-of select="$section_number"/></NUMBER>
+      <SUMMARY>&lt;span style="font-weight: bold;"&gt;<xsl:value-of select="title"/>&lt;/span&gt;</SUMMARY>
+      <VISIBLE>1</VISIBLE>
+      <MODS>
+        
+        <xsl:if test="$recurse = 'true'">
+          <xsl:variable name="mod_number" select="substring-after(@identifierref,'res')"/>
+          <xsl:call-template name="item_recurse_files" >
+                <xsl:with-param name="mod_number" select="$mod_number"/>
+                <xsl:with-param name="indent" >0</xsl:with-param>
+                <xsl:with-param name="recurse" select="$recurse" />
+          </xsl:call-template>
+        
+        </xsl:if>
+
+        <xsl:if test="$recurse = 'false'">
+        <xsl:for-each select="item">
+          <xsl:variable name="mod_number" select="substring-after(@identifierref,'res')"/>
+          <xsl:call-template name="item" >
+                <xsl:with-param name="mod_number" select="$mod_number"/>
+                <xsl:with-param name="indent" >0</xsl:with-param>
+              </xsl:call-template>
+        </xsl:for-each> 
+        </xsl:if>
+  
+
+      </MODS>
+    </SECTION>
+  </xsl:template>
+
+<xsl:template name="item_recurse_files">
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+   <xsl:param name="recurse"/>
+
+   
+    <!-- Create one section-mod -->
+    <xsl:for-each select="document(concat(@identifierref,'.dat'))">
+      <xsl:call-template name="section_mod">
+          <xsl:with-param name="mod_number" select="$mod_number"/>
+          <xsl:with-param name="indent" select="$indent"/>
+      </xsl:call-template>
+    </xsl:for-each>
+    
+    <!-- Depth first recursion to preserve order -->
+    <xsl:for-each select="item">
+      <xsl:variable name="m_number" select="substring-after(@identifierref,'res')"/>
+      <xsl:call-template name="item_recurse_files" >
+            <xsl:with-param name="mod_number" select="$m_number"/>
+            <xsl:with-param name="indent" select="$indent + 1"/>
+      </xsl:call-template>
+    </xsl:for-each>
+    
+</xsl:template>
+
+<xsl:template name="item">
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+
+   <GETHERE></GETHERE> 
+   <xsl:if test="document(concat(@identifierref,'.dat'))/CONTENT/FLAGS/ISFOLDER/@value != 'true' or document(concat(@identifierref,'.dat'))/EXTERNALLINK/DESCRIPTION/FLAGS/ISHTML/@value ='true'">
+    <!-- Create one section-mod -->
+    <xsl:for-each select="document(concat(@identifierref,'.dat'))">
+      <xsl:call-template name="section_mod">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+            <xsl:with-param name="indent" select="$indent"/>
+      </xsl:call-template>
+    </xsl:for-each>
+   </xsl:if>
+   
+    
+</xsl:template>
+
+<!-- Determines the type of section mod entry and calls the appropriate creation template -->
+<xsl:template name="section_mod" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="contenttype" />
+   <xsl:param name="indent">1. </xsl:param>
+
+  <!-- Every file will have a label module describing it -->
+  <xsl:choose>
+      <!-- Detected a file -->
+      <xsl:when test="CONTENT/FILE/@id != '' or CONTENT/FILES/FILE/NAME != ''">
+        <!-- Create a label -->
+        <xsl:call-template name="section_mod_label">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+        </xsl:call-template>
+
+        <!-- Create a resource -->
+        <xsl:call-template name="section_mod_resource">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+        </xsl:call-template>
+
+      </xsl:when>
+
+      <!-- Detected a folder -->
+      <xsl:when test="CONTENT/FLAGS/ISFOLDER/@value = 'true'">
+        <MAKINGLABEL></MAKINGLABEL>
+        <!-- Create a label -->
+        <xsl:call-template name="section_mod_label">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+            </xsl:call-template>
+      </xsl:when>
+
+      <!-- Detected text -->
+      <xsl:when test="CONTENT/MAINDATA/FLAGS/ISHTML/@value = 'true' or CONTENT/BODY/TYPE/@value = 'H' ">
+        <MAKINGTEXT></MAKINGTEXT>
+        <!-- Create a resource -->
+        <xsl:call-template name="section_mod_resource">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+        </xsl:call-template>
+      </xsl:when>
+
+      <!-- Detected external link -->
+      <xsl:when test="EXTERNALLINK/TITLE/@value != '' ">
+         <!-- Create a label -->
+        <xsl:call-template name="section_mod_label">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+        </xsl:call-template>
+
+        <!-- Create a resource -->
+        <xsl:call-template name="section_mod_externallink">
+              <xsl:with-param name="mod_number" select="$mod_number"/>
+              <xsl:with-param name="indent" select="$indent"/>
+        </xsl:call-template>
+      </xsl:when>
+      <xsl:otherwise>
+        <UNKNOWN>
+        </UNKNOWN>
+      </xsl:otherwise>
+
+  </xsl:choose>
+
+
+</xsl:template>
+
+<!-- Creates one section-mod-label -->
+<xsl:template name="section_mod_label" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+  <MOD>
+    <ID>1<xsl:value-of select="$mod_number"/>0</ID>
+         <ZIBA_NAME>
+      <!-- BB5.5 -->
+      <xsl:value-of select="CONTENT/TITLE"/>
+      <!-- BB6 -->
+      <xsl:value-of select="CONTENT/TITLE/@value"/>
+         </ZIBA_NAME>
+    <TYPE>label</TYPE>
+    <INSTANCE><xsl:value-of select="$mod_number"/></INSTANCE>
+    <ADDED>1094240775</ADDED>
+    <DELETED>0</DELETED>
+    <SCORE>0</SCORE>
+    <INDENT><xsl:value-of select="$indent"/></INDENT>
+    <VISIBLE>1</VISIBLE>
+    <GROUPMODE>0</GROUPMODE>
+  </MOD>
+   
+</xsl:template>
+
+<!-- Creates one section-mod-resource -->
+<xsl:template name="section_mod_resource" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/>0</ID>
+         <ZIBA_NAME>
+      <!-- BB5.5 -->
+      <xsl:value-of select="CONTENT/TITLE"/>
+      <!-- BB6 -->
+      <xsl:value-of select="CONTENT/TITLE/@value"/>
+         </ZIBA_NAME>
+    <TYPE>resource</TYPE>
+    <INSTANCE><xsl:value-of select="$mod_number"/></INSTANCE>
+    <ADDED>1094240775</ADDED>
+    <DELETED>0</DELETED>
+    <SCORE>0</SCORE>
+    <INDENT><xsl:value-of select="$indent"/></INDENT>
+    <VISIBLE>1</VISIBLE>
+    <GROUPMODE>0</GROUPMODE>
+  </MOD>
+   
+</xsl:template>
+
+<!-- Creates one section-mod-externallink -->
+<xsl:template name="section_mod_externallink" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="indent">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/>0</ID>
+         <ZIBA_NAME>
+      <xsl:value-of select="EXTERNALLINK/TITLE/@value"/>
+         </ZIBA_NAME>
+    <TYPE>resource</TYPE>
+    <INSTANCE><xsl:value-of select="$mod_number"/></INSTANCE>
+    <ADDED>1094240775</ADDED>
+    <DELETED>0</DELETED>
+    <SCORE>0</SCORE>
+    <INDENT><xsl:value-of select="$indent"/></INDENT>
+    <VISIBLE>1</VISIBLE>
+    <GROUPMODE>0</GROUPMODE>
+  </MOD>
+   
+</xsl:template>
+
+<!-- Creates a module-label entry -->
+<xsl:template name="module_label" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>label</MODTYPE>
+    <NAME>
+      <!-- for CONTENT text -->
+      <xsl:value-of select="TITLE"/>
+      <!-- for EXTERNALLINK text -->
+      <xsl:value-of select="TITLE/@value"/>
+    </NAME>
+    <CONTENT>
+      &lt;span style="font-style: italic;"&gt;
+      <!-- for CONTENT text -->
+      <xsl:value-of select="TITLE"/>
+      <!-- for EXTERNALLINK text -->
+      <xsl:value-of select="TITLE/@value"/>
+      :&lt;/span&gt;
+      <!-- for CONTENT text -->
+      <xsl:value-of select="MAINDATA/TEXT"/> 
+      <!-- for EXTERNALLINK text -->
+      <xsl:value-of select="DESCRIPTION/TEXT"/> 
+      <!-- for BB6 text -->
+      <xsl:value-of select="BODY/TEXT"/> 
+    </CONTENT>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+   
+<!-- Creates one module-file entry -->
+<xsl:template name="module_file" >
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="identifier"/>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>resource</MODTYPE>
+    <NAME>
+      <!-- BB5 -->
+     <xsl:value-of select="FILES/FILEREF/RELFILE/@value"/>
+      <!-- BB6 -->
+     <xsl:value-of select="FILES/FILE/NAME"/>
+    </NAME>
+    <TYPE>file</TYPE>
+    <REFERENCE><!-- BB5 --><xsl:value-of select="FILES/FILEREF/CONTENTID/@value"/><!-- BB6 --><xsl:value-of select="$identifier"/>/<!-- BB5 --><xsl:value-of select="FILES/FILEREF/RELFILE/@value"/><!-- BB6 --><xsl:value-of select="FILES/FILE/NAME"/></REFERENCE>
+    <SUMMARY>
+     <xsl:value-of select="MAINDATA/TEXT"/>
+    </SUMMARY>
+    <ALLTEXT></ALLTEXT>
+    <POPUP></POPUP>
+    <OPTIONS>frame</OPTIONS>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+
+<!-- Creates one module-text entry -->
+<xsl:template name="module_text" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>resource</MODTYPE>
+    <NAME>
+      <!-- BB5.5 -->
+      <xsl:value-of select="TITLE"/>
+      <!-- BB6 -->
+      <xsl:value-of select="TITLE/@value"/>
+    </NAME>
+    <TYPE>text</TYPE>
+    <REFERENCE></REFERENCE>
+    <SUMMARY>
+      <!-- BB5.5 -->
+      <xsl:value-of select="TITLE"/>
+      <!-- BB6 -->
+      <xsl:value-of select="TITLE/@value"/>
+    </SUMMARY>
+    <ALLTEXT>
+      <!-- BB5.5 -->
+      <xsl:value-of select="MAINDATA/TEXT"/>
+      <!-- BB6 -->
+      <xsl:value-of select="BODY/TEXT"/>
+    </ALLTEXT>
+    <POPUP></POPUP>
+    <OPTIONS></OPTIONS>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+
+<!-- Creates one module-link entry -->
+<xsl:template name="module_link" >
+   <xsl:param name="mod_number">1. </xsl:param>
+  <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+    <MODTYPE>resource</MODTYPE>
+    <NAME>
+      <xsl:value-of select="URL/@value"/>
+    </NAME>
+    <TYPE>file</TYPE>
+    <REFERENCE>
+      <xsl:value-of select="URL/@value"/>
+    </REFERENCE>
+    <SUMMARY>
+      <xsl:value-of select="TITLE/@value"/>&lt;br/&gt;
+      <xsl:value-of select="URL/@value"/>
+    </SUMMARY>
+    <ALLTEXT>
+      <xsl:value-of select="DESCRIPTION/TEXT"/>
+    </ALLTEXT>
+    <POPUP></POPUP>
+    <OPTIONS>frame</OPTIONS>
+    <TIMEMODIFIED>1094240775</TIMEMODIFIED>
+  </MOD>
+</xsl:template>
+
+<!-- Create a CONTENT module entries -->
+<xsl:template match="EXTERNALLINK">
+   <xsl:param name="mod_number">1. </xsl:param>
+       <!-- Every link module will have a label module describing it -->
+       <xsl:call-template name="module_label">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+       
+       <xsl:call-template name="module_link">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+
+</xsl:template>
+
+<!-- Create a CONTENT module entries -->
+<xsl:template match="CONTENT">
+   <xsl:param name="mod_number">1. </xsl:param>
+   <xsl:param name="identifier"/>
+
+  <xsl:choose>
+    <!-- Detected a file 
+    
+      <FILEFOUND></FILEFOUND>
+    -->
+      <xsl:when test="FILES/FILE/@id != ''">
+
+       <!-- Every file module will have a label module describing it -->
+       <xsl:call-template name="module_label">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+       
+       <xsl:call-template name="module_file">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+        <xsl:with-param name="identifier" select="$identifier"/>
+       </xsl:call-template>
+
+      </xsl:when>
+      
+      <!-- Detected a folder 
+     <FOLDERFOUND></FOLDERFOUND>
+      -->
+      <xsl:when test="FLAGS/ISFOLDER/@value = 'true'">
+        
+        <xsl:call-template name="module_label">
+          <xsl:with-param name="mod_number" select="$mod_number"/>
+        </xsl:call-template>
+        
+      </xsl:when>
+      
+      <!-- Detected text 
+     <TEXTFOUND></TEXTFOUND>
+      -->
+      <xsl:when test="MAINDATA/FLAGS/ISHTML/@value = 'true' or BODY/TYPE/@value = 'H' ">
+        
+       <xsl:call-template name="module_text">
+        <xsl:with-param name="mod_number" select="$mod_number"/>
+       </xsl:call-template>
+      
+      </xsl:when>
+    
+      <xsl:otherwise>
+    <UNKNOWN>
+      <xsl:value-of select="TITLE"/>
+    </UNKNOWN>
+        </xsl:otherwise>
+  </xsl:choose>
+
+</xsl:template>
+
+
+<!-- Creates all module entries -->
+<xsl:template name="modules" match="resource">
+  <MODULES>
+    <xsl:for-each select="//resource">
+    <xsl:variable name="mod_number" select="substring-after(@identifier,'res')"/>
+    <xsl:variable name="identifier" select="@identifier"/>
+    <xsl:for-each select="document(concat(@identifier,'.dat'))">
+          <xsl:apply-templates select="//FORUM">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+          </xsl:apply-templates>
+          <xsl:apply-templates select="//CONTENT">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+            <xsl:with-param name="identifier" select="$identifier"/>
+          </xsl:apply-templates>
+          <xsl:apply-templates select="//EXTERNALLINK">
+            <xsl:with-param name="mod_number" select="$mod_number"/>
+          </xsl:apply-templates>
+    </xsl:for-each>
+  </xsl:for-each>
+</MODULES>
+</xsl:template>
+  
+<!-- ############# Forum conversion ################# -->
+
+<xsl:template match="FORUM">
+   <xsl:param name="mod_number">1. </xsl:param>
+       <MOD>
+    <ID><xsl:value-of select="$mod_number"/></ID>
+               <MODTYPE>forum</MODTYPE>
+               <TYPE>general</TYPE>
+         <NAME>
+      <xsl:value-of select="TITLE/@value"/>
+         </NAME>
+         <INTRO>
+      <xsl:value-of select="DESCRIPTION/TEXT"/> 
+         </INTRO>
+         <OPEN>2</OPEN>
+         <ASSESSED>0</ASSESSED>
+         <ASSESSPUBLIC>0</ASSESSPUBLIC>
+         <ASSESSTIMESTART>0</ASSESSTIMESTART>
+         <ASSESSTIMEFINISH>0</ASSESSTIMEFINISH>
+         <MAXBYTES>0</MAXBYTES>
+         <SCALE>0</SCALE>
+         <FORCESUBSCRIBE>0</FORCESUBSCRIBE>
+         <RSSTYPE>0</RSSTYPE>
+         <RSSARTICLES>0</RSSARTICLES>
+         <TIMEMODIFIED></TIMEMODIFIED>
+    <!--
+    <DISCUSSIONS>
+      <xsl:for-each select="MESSAGETHREADS/MSG">
+      <xsl:variable name="discussion_id" select="position()"/>
+      <DISCUSSION>
+        <ID>
+          <xsl:value-of select="$mod_number"/>0<xsl:value-of select="$discussion_id"/>
+        </ID>
+        <NAME>
+          <xsl:value-of select="TITLE/@value"/> 
+        </NAME>
+        <FIRSTPOST>2</FIRSTPOST>
+        <USERID>1</USERID>
+        <GROUPID>-1</GROUPID>
+        <ASSESSED>1</ASSESSED>
+        <TIMEMODIFIED>1094748430</TIMEMODIFIED>
+        <USERMODIFIED>1</USERMODIFIED>
+        <POSTS>
+          <xsl:call-template name="MSG">
+            <xsl:with-param name="parent" select="0"/>
+            <xsl:with-param name="post_id">
+            <xsl:value-of select="$mod_number"/>0<xsl:value-of select="$discussion_id"/>0<xsl:value-of select="position()"/>
+            </xsl:with-param>
+          </xsl:call-template>
+        </POSTS>
+      </DISCUSSION>
+      </xsl:for-each>
+    </DISCUSSIONS>
+      -->
+       </MOD>
+</xsl:template>
+
+<xsl:template name="MSG" match="MSG">
+    <xsl:param name="parent" select="1"/>
+    <xsl:param name="post_id" select="1"/>
+    <POST>
+      <ID><xsl:value-of select="$post_id"/></ID>
+      <PARENT> <xsl:value-of select="$parent"/></PARENT>
+      <USERID>1</USERID>
+      <CREATED>1094748430</CREATED>
+      <MODIFIED>1094748430</MODIFIED>
+      <MAILED>1</MAILED>
+      <SUBJECT><xsl:value-of select="TITLE/@value"/></SUBJECT>
+      <MESSAGE><xsl:value-of select="MESSAGETEXT"/></MESSAGE>
+      <FORMAT>1</FORMAT>
+      <ATTACHMENT></ATTACHMENT>
+      <TOTALSCORE>0</TOTALSCORE>
+    </POST>
+
+      <xsl:for-each select="MSG">
+          <xsl:call-template name="MSG">
+            <xsl:with-param name="parent" select="$post_id"/>
+            <xsl:with-param name="post_id">
+            <xsl:value-of select="$post_id"/>0<xsl:value-of select="position()"/>
+            </xsl:with-param>
+          </xsl:call-template>
+      </xsl:for-each>
+</xsl:template>
+</xsl:stylesheet>
+
+
+
+
diff --git a/backup/bb/restore_bb.php b/backup/bb/restore_bb.php
new file mode 100644 (file)
index 0000000..238b8a6
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+// This file facilitates the conversion of a Blackboard course export
+// into a Moodle course export.  It assumes an unzipped directory and makes in-place alterations.
+  
+// Ziba Scott <ziba@linuxbox.com> 10-25-04
+  
+function get_subdirs($directory){
+    $opendirectory = opendir( $directory );
+    while($filename = readdir($opendirectory)) {
+        if (is_dir($directory.$filename) and $filename != ".." and $filename != "."){
+            $subdirs[] = $filename;
+        }
+    }
+    closedir($opendirectory);
+    return $subdirs;
+}
+
+
+function choose_bb_xsl($manifest){
+    $f = fopen($manifest,"r");
+    $buffer = fgets($f, 400);
+    $buffer = fgets($f, 400);
+    fclose($f);
+    if (strstr($buffer,"xmlns:bb=\"http://www.blackboard.com/content-packaging/\"")){
+        return "bb6_to_moodle.xsl";
+    }
+    return "bb5.5_to_moodle.xsl";
+}
+
+
+function blackboard_convert($dir){
+    global $CFG;
+
+    if (!function_exists('xslt_create')) {  // XSLT MUST be installed for this to work
+        return true;
+    }
+
+    // Check for a Blackboard manifest file
+    if(is_file($dir."/imsmanifest.xml")){
+
+        //Select the proper XSL file
+        $xslt_file = choose_bb_xsl($dir."/imsmanifest.xml");
+
+        //TODO: Use the get_string function
+        echo "<li>Converting Blackboard export</li>";
+
+        // The XSL file must be in the same directory as the Blackboard files when it is processed
+        copy($CFG->dirroot."/backup/bb/$xslt_file", "$dir/$xslt_file");
+        $startdir = getcwd();
+        chdir($dir);
+
+
+        // Process the Blackboard XML files with the chosen XSL file.
+        // The imsmanifest contains all the XML files and their relationships. 
+        // The XSL processor will open them as needed.
+        $xsltproc = xslt_create();
+        if (!xslt_process($xsltproc, "imsmanifest.xml", $xslt_file, "$dir/moodle.xml")) {
+            dump("Failed writing xml file");
+            chdir($startdir);
+            return false;
+        }
+
+
+        // Copy the Blackboard course files into the moodle course_files structure
+        $subdirs = get_subdirs($dir."/");
+        mkdir("$dir/course_files");
+        foreach ($subdirs as $subdir){
+            rename($subdir, "course_files/$subdir");
+        }
+
+        chdir($startdir);
+
+        // Blackboard export successfully converted
+        return true;
+    }
+    // This is not a Blackboard export
+    return true;
+
+}
+
+?>
index 4bf37a62ca04e9911c37b4bab12afd8476f7d6b7..5ec5769ec5fa2d92c58cd24820dfe9dcc5f1503c 100644 (file)
@@ -9,6 +9,7 @@
     require_once ("../course/lib.php");
     require_once ("lib.php");
     require_once ("restorelib.php");
+    require_once ("bb/restore_bb.php");
     require_once("$CFG->libdir/blocklib.php");
 
     //Optional
index 801974ebdc4ae3beca8d61030c419cfe2c60d3f8..bad9eaa06c279a9f96dd5ac83c6931b81ae44abe 100644 (file)
                 notify("Error unzipping backup file. Invalid zip file.");
             }
         }
+
+        //Check for Blackboard backups and convert
+        if ($status){
+            require_once("$CFG->dirroot/backup/bb/restore_bb.php");
+            echo "<li>".get_string("checkingforbbexport");
+            $status = blackboard_convert($CFG->dataroot."/temp/backup/".$backup_unique_code);
+        }
         
         //Now check for the moodle.xml file
         if ($status) {