[LON-CAPA-cvs] cvs: doc /loncapafiles loncapafiles.lpml loncom/imspackages imsexport.pm loncom/interface londocs.pm lonfeedback.pm
raeburn
lon-capa-cvs@mail.lon-capa.org
Thu, 23 Dec 2004 14:00:59 -0000
This is a MIME encoded message
--raeburn1103810459
Content-Type: text/plain
raeburn Thu Dec 23 09:00:59 2004 EDT
Added files:
/loncom/imspackages imsexport.pm
Modified files:
/loncom/interface londocs.pm lonfeedback.pm
/doc/loncapafiles loncapafiles.lpml
Log:
Export to IMS now exports discussion content - uses lonfeedback::listdiscussion(). Modification to export of templated documents (syllabus, aboutme, simplepage etc.) to IMS. Simple problems now converted to standard LON-CAPA problem format before export to IMS. Same routines could be used to dump simple problems to CSTR.
--raeburn1103810459
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20041223090059.txt"
Index: loncom/interface/londocs.pm
diff -u loncom/interface/londocs.pm:1.157 loncom/interface/londocs.pm:1.158
--- loncom/interface/londocs.pm:1.157 Wed Dec 15 10:21:43 2004
+++ loncom/interface/londocs.pm Thu Dec 23 09:00:58 2004
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.157 2004/12/15 15:21:43 raeburn Exp $
+# $Id: londocs.pm,v 1.158 2004/12/23 14:00:58 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -30,6 +30,7 @@
use strict;
use Apache::Constants qw(:common :http);
+use Apache::imsexport;
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonratedt;
@@ -319,7 +320,7 @@
}
$r->print('<html><head><title>Export Course</title></head>'.
- &Apache::loncommon::bodytag('Export course to IMS or SCORM content package'));
+ &Apache::loncommon::bodytag('Export course to IMS content package'));
$r->print($outcome);
$r->print('</body></html>');
} else {
@@ -368,6 +369,12 @@
}
if (ref($curRes)) {
my $symb = $curRes->symb();
+ my $ressymb = $symb;
+ if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) {
+ unless ($ressymb =~ m|adm/wrapper/adm|) {
+ $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
+ }
+ }
my $color = $count%2;
$display .='<tr bgcolor='.$bgcolors[$color].'><td>'."\n".
'<input type="checkbox" name="archive" value="'.$count.'" ';
@@ -389,7 +396,7 @@
my $currelem = $count+$boards+$startcount;
$children{$parent{$depth}} .= $currelem.':';
$display .= ' '.$curRes->title().'</td>';
- if ($discussiontime{$symb} > 0) {
+ if ($discussiontime{$ressymb} > 0) {
$boards ++;
$currelem = $count+$boards+$startcount;
$display .= '<td> </td><td align="right"><input type="checkbox" name="discussion" value="'.$count.'" /> </td>'."\n";
@@ -402,13 +409,23 @@
<script>
function checkAll(field) {
- for (i = 0; i < field.length; i++)
- field[i].checked = true ;
+ if (field.length > 0) {
+ for (i = 0; i < field.length; i++) {
+ field[i].checked = true ;
+ }
+ } else {
+ field.checked = true
+ }
}
-
+
function uncheckAll(field) {
- for (i = 0; i < field.length; i++)
- field[i].checked = false ;
+ if (field.length > 0) {
+ for (i = 0; i < field.length; i++) {
+ field[i].checked = false ;
+ }
+ } else {
+ field.checked = false ;
+ }
}
function propagateCheck(item) {
@@ -444,7 +461,7 @@
</script>
|;
$r->print('<html><head><title>Export Course</title>'.$scripttag.'</head>'.
- &Apache::loncommon::bodytag('Export course to IMS or SCORM content package'
+ &Apache::loncommon::bodytag('Export course to IMS content package'
));
$r->print($display.'</table>'.
@@ -482,7 +499,7 @@
' identifier="MANIFEST-'.$ENV{'request.course.id'}.'-'.$now.'"'.
' xsi:schemaLocation="http://www.imsglobal.org/xsd/imscp_v1p1imscp_v1p1.xsd'.
' http://www.imsglobal.org/xsd/imsmd_v1p2 imsmd_v1p2p2.xsd">'."\n".
-' <organizations default="ORG-."'.$ENV{'request,course.id'}.'-'.$now.'">'."\n".
+' <organizations default="ORG-'.$ENV{'request.course.id'}.'-'.$now.'">'."\n".
' <organization identifier="ORG-'.$ENV{'request.course.id'}.'-'.$now.'"'.
' structure="hierarchical">'."\n".
' <title>'.$ENV{'request.'.$ENV{'request.course.id'}.'.description'}.'</title>'
@@ -581,6 +598,22 @@
$imsresources .=
' <file href="'.$_.'" />'."\n";
}
+ if (grep/^$count$/,@$discussions) {
+ my $ressymb = $symb;
+ my $mode;
+ if ($ressymb =~ m|adm/(\w+)/(\w+)/(\d+)/bulletinboard$|) {
+ unless ($ressymb =~ m|adm/wrapper/adm|) {
+ $ressymb = 'bulletin___'.$3.'___adm/wrapper/adm/'.$1.'/'.$2.'/'.$3.'/bulletinboard';
+ }
+ $mode = 'board';
+ }
+ my %extras = (
+ caller => 'imsexport',
+ tempexport => $tempexport,
+ count => $count
+ );
+ my $discresult = &Apache::lonfeedback::list_discussion($mode,undef,$ressymb,\%extras);
+ }
$imsresources .= ' </resource>'."\n";
}
}
@@ -623,24 +656,52 @@
my $message;
# find where user is author or co-author
my %roleshash = &Apache::lonnet::get_my_roles();
+ my @uploads = ();
if ($curRes->is_sequence()) {
$content_type = 'sequence';
} elsif ($curRes->is_page()) {
$content_type = 'page'; # need to handle individual items in pages.
} elsif ($symb =~ m-public/$cdom/$cnum/syllabus$-) {
$content_type = 'syllabus';
+ my $contents = &Apache::imsexport::templatedpage($content_type);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
} elsif ($symb =~ m-\.sequence___\d+___ext-) {
$content_type = 'external';
+ my $title = $curRes->title;
+ my $contents = &Apache::imsexport::external($symb,$title);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
} elsif ($symb =~ m-adm/navmaps$-) {
$content_type = 'navmap';
- } elsif ($symb =~ m-adm/$cdom/$cnum/\d+/smppg$-) {
+ } elsif ($symb =~ m-adm/[^/]+/[^/]+/(\d+)/smppg$-) {
$content_type = 'simplepage';
- } elsif ($symb =~ m-/lib/templates/simpleproblem\.problem$-) {
+ my $contents = &Apache::imsexport::templatedpage($content_type,$1,$count,\@uploads);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-lib/templates/simpleproblem\.problem$-) {
$content_type = 'simpleproblem';
- } elsif ($symb =~ m-adm/$cdom/$cnum/\d+/bulletinboard$-) {
+ my $contents = &Apache::imsexport::simpleproblem($symb);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-lib/templates/examupload\.problem-m) {
+ $content_type = 'examupload';
+ } elsif ($symb =~ m-adm/(\w+)/(\w+)/(\d+)/bulletinboard$-) {
$content_type = 'bulletinboard';
- } elsif ($symb =~ m-adm/$cdom/$cnum/\d+/aboutme$-) {
+ my $contents = &Apache::imsexport::templatedpage($content_type,$3,$count,\@uploads,$1,$2);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
+ } elsif ($symb =~ m-adm/([^/]+)/([^/]+)/aboutme$-) {
$content_type = 'aboutme';
+ my $contents = &Apache::imsexport::templatedpage($content_type,undef,$count,\@uploads,$1,$2);
+ if ($contents) {
+ $$content_file = &store_template($contents,$tempexport,$count,$content_type);
+ }
} elsif ($symb =~ m-uploaded/$cdom/$cnum-) {
$$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'uploaded');
} elsif ($symb =~ m-\.(sequence|page)___\d+___uploaded/$cdom/$cnum/-) {
@@ -665,6 +726,15 @@
$$content_file = &replicate_content($cdom,$cnum,$tempexport,$symb,$count,\$message,$href,'noedit');
}
}
+ if (@uploads > 0) {
+ foreach my $item (@uploads) {
+ my $uploadmsg = '';
+ &replicate_content($cdom,$cnum,$tempexport,$item,$count,\$uploadmsg,$href,'uploaded');
+ if ($uploadmsg) {
+ $$copyresult .= $uploadmsg."\n";
+ }
+ }
+ }
if ($message) {
$$copyresult .= $message."\n";
}
@@ -735,6 +805,19 @@
return;
}
+sub store_template {
+ my ($contents,$tempexport,$count,$content_type) = @_;
+ if ($contents) {
+ my $destination = $tempexport.'/resources/'.$count.'/'.$content_type.'.xml';
+ my $storetemplate;
+ if ($storetemplate = Apache::File->new('>'.$destination)) {
+ print $storetemplate $contents;
+ close($storetemplate);
+ }
+ return $count.'/'.$content_type.'.xml';
+ }
+}
+
# Imports the given (name, url) resources into the course
# coursenum, coursedom, and folder must precede the list
sub group_import {
Index: loncom/interface/lonfeedback.pm
diff -u loncom/interface/lonfeedback.pm:1.146 loncom/interface/lonfeedback.pm:1.147
--- loncom/interface/lonfeedback.pm:1.146 Thu Dec 23 08:28:50 2004
+++ loncom/interface/lonfeedback.pm Thu Dec 23 09:00:58 2004
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Feedback
#
-# $Id: lonfeedback.pm,v 1.146 2004/12/23 13:28:50 raeburn Exp $
+# $Id: lonfeedback.pm,v 1.147 2004/12/23 14:00:58 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -68,13 +68,18 @@
}
sub list_discussion {
- my ($mode,$status,$ressymb)=@_;
+ my ($mode,$status,$ressymb,$imsextras)=@_;
my $outputtarget=$ENV{'form.grade_target'};
if (defined($ENV{'form.export'})) {
if($ENV{'form.export'}) {
$outputtarget = 'export';
}
}
+ if (defined($imsextras)) {
+ if ($$imsextras{'caller'} eq 'imsexport') {
+ $outputtarget = 'export';
+ }
+ }
if (not &discussion_visible($status)) { return ''; }
my @bgcols = ("#cccccc","#eeeeee");
my $discussiononly=0;
@@ -325,15 +330,26 @@
} elsif ($outputtarget eq 'export') {
# Create temporary directory if this is an export
my $now = time;
- $tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports';
- if (!-e $tempexport) {
- mkdir($tempexport,0700);
- }
- $tempexport .= '/'.$now;
- if (!-e $tempexport) {
- mkdir($tempexport,0700);
+ if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) {
+ $tempexport = $$imsextras{'tempexport'};
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ $tempexport .= '/'.$$imsextras{'count'};
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ } else {
+ $tempexport = $Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/ims_exports';
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ $tempexport .= '/'.$now;
+ if (!-e $tempexport) {
+ mkdir($tempexport,0700);
+ }
+ $tempexport .= '/'.$ENV{'user.domain'}.'_'.$ENV{'user.name'};
}
- $tempexport .= '/'.$ENV{'user.domain'}.'_'.$ENV{'user.name'};
if (!-e $tempexport) {
mkdir($tempexport,0700);
}
@@ -634,27 +650,31 @@
</manifest>
|;
close($manifestfile);
+ if ((defined($imsextras)) && ($$imsextras{'caller'} eq 'imsexport')) {
+ $discussion = $copyresult;
+ } else {
#Create zip file in prtspool
- my $imszipfile = '/prtspool/'.
- $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
- time.'_'.rand(1000000000).'.zip';
+ my $imszipfile = '/prtspool/'.
+ $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.zip';
# zip can cause an sh launch which can pass along all of %ENV
# which can be too large for /bin/sh to handle
- my %oldENV=%ENV;
- undef(%ENV);
- my $cwd = &getcwd();
- my $imszip = '/home/httpd/'.$imszipfile;
- chdir $tempexport;
- open(OUTPUT, "zip -r $imszip * 2> /dev/null |");
- close(OUTPUT);
- chdir $cwd;
- %ENV=%oldENV;
- undef(%oldENV);
- $discussion .= 'Download the zip file from <a href="'.$imszipfile.'">Discussion Posting Archive</a><br />';
- if ($copyresult) {
- $discussion .= 'The following errors occurred during export - <br />'.$copyresult;
+ my %oldENV=%ENV;
+ undef(%ENV);
+ my $cwd = &getcwd();
+ my $imszip = '/home/httpd/'.$imszipfile;
+ chdir $tempexport;
+ open(OUTPUT, "zip -r $imszip * 2> /dev/null |");
+ close(OUTPUT);
+ chdir $cwd;
+ %ENV=%oldENV;
+ undef(%oldENV);
+ $discussion .= 'Download the zip file from <a href="'.$imszipfile.'">Discussion Posting Archive</a><br />';
+ if ($copyresult) {
+ $discussion .= 'The following errors occurred during export - <br />'.$copyresult;
+ }
}
} else {
$discussion .= '<br />Unfortunately you will not be able to retrieve an archive of the discussion posts at this time, because there was a problem creating a manifest file.<br />';
Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.403 doc/loncapafiles/loncapafiles.lpml:1.404
--- doc/loncapafiles/loncapafiles.lpml:1.403 Mon Dec 13 11:52:29 2004
+++ doc/loncapafiles/loncapafiles.lpml Thu Dec 23 09:00:58 2004
@@ -2,7 +2,7 @@
"http://lpml.sourceforge.net/DTD/lpml.dtd">
<!-- loncapafiles.lpml -->
-<!-- $Id: loncapafiles.lpml,v 1.403 2004/12/13 16:52:29 www Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.404 2004/12/23 14:00:58 raeburn Exp $ -->
<!--
@@ -2134,6 +2134,15 @@
<status>works/unverified</status>
</file>
<file>
+<source>loncom/imspackages/imsexport.pm</source>
+<target dist='default'>home/httpd/lib/perl/Apache/imsexport.pm</target>
+<categoryname>handler</categoryname>
+<description>
+Routines used in londocs to export templated files to an IMS package.
+</description>
+<status>works/unverified</status>
+</file>
+<file>
<source>loncom/interface/lonhelp.pm</source>
<target dist='default'>home/httpd/lib/perl/Apache/lonhelp.pm</target>
<categoryname>handler</categoryname>
Index: loncom/imspackages/imsexport.pm
+++ loncom/imspackages/imsexport.pm
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
package Apache::imsexport;
use strict;
use Apache::lonnet;
sub simpleproblem {
my ($symb,$output) = @_;
my %qparms = &Apache::lonnet::dump('resourcedata',
$ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
$ENV{'course.'.$ENV{'request.course.id'}.'.num'},
$ENV{'request.course.id'}.'.'.$symb);
if ($symb) {
my $prefix=$ENV{'request.course.id'}.'.'.$symb.'.0.';
my $qtype=$qparms{$prefix.'questiontype'};
my $qtext=$qparms{$prefix.'questiontext'};
my $hint=$qparms{$prefix.'hinttext'};
my %values = ();
my %foils = ();
if (($qtype eq 'radio') || ($qtype eq 'option')) {
my $maxfoils=$qparms{$prefix.'maxfoils'};
my $randomize=$qparms{$prefix.'randomize'};
if ($qtype eq 'option') {
my $options=$qparms{$prefix.'options'};
%values = &evaloptionhash($options);
$$output .= qq|
<problem>
<optionresponse max="$maxfoils" randomize="$randomize">
<foilgroup options="$options">
|;
for (my $k=0; $k<10; $k++) {
my $iter = $k+1;
$$output .= ' <foil name="foil'.$k.'" value="'.$qparms{$prefix.'.value.'.$iter}.'"';
$$output .= 'location="'.$qparms{$prefix.'.position.'.$iter}.'" ';
$$output .= '><startouttext />'.$qparms{$prefix.'.text.'.$iter}.'<endouttext /></foil>'."\n";
}
chomp($$output);
$$output .= qq|
</foilgroup>
|;
if ($hint) {
$$output .= '
<hintgroup>
<hintpart on="default">
<startouttext />'.$hint.'<endouttext/>
</hintpart>
</hintgroup>';
}
$$output .= qq|
</optionresponse>
</problem>
|;
} else {
$$output .= qq|
<problem>
<radiobuttonresponse max="$maxfoils" randomize="$randomize">
<foilgroup>
|;
for (my $k=0; $k<10; $k++) {
my $iter = $k+1;
$$output .= ' <foil name="foil'.$k.'" value="'.$qparms{$prefix.'.value.'.$iter}.'"';
$$output .= 'location="'.$qparms{$prefix.'.position.'.$iter}.'" ';
$$output .= '><startouttext />'.$qparms{$prefix.'.text.'.$iter}.'<endouttext /></foil>'."\n";
}
chomp($$output);
$$output .= qq|
</foilgroup>
|;
if ($hint) {
$$output .= '
<hintgroup>
<hintpart on="default">
<startouttext />'.$hint.'<endouttext/>
</hintpart>
</hintgroup>';
}
$$output .= qq|
</radiobuttonresponse>
</problem>
|;
}
} elsif ($qtype eq 'stringanswer') {
my $stringanswer = $qparms{$prefix.'stringanswer'};
my $stringtype=$qparms{$prefix.'stringtype'};
$$output .= qq|
<problem>
<stringresponse answer="$stringanswer" type="$stringtype">
<textline>
</textline>
|;
if ($hint) {
$$output .= '
<hintgroup>
<hintpart on="default">
<startouttext />'.$hint.'<endouttext/>
</hintpart>
</hintgroup>';
}
$$output .= qq|
</stringresponse>
</problem>
|;
} else {
$$output .= qq|
<problem>
<startouttext />$qtext<endouttext />
<essayresponse>
<textfield></textfield>
</essayresponse>
</problem>
|;
}
}
return;
}
sub evaloptionhash {
my $options=shift;
$options=~s/^\(\'//;
$options=~s/\'\)$//;
my %returnhash=();
foreach (split(/\'\,\'/,$options)) {
$returnhash{$_}=$_;
}
return %returnhash;
}
sub external {
my ($symb,$title) = @_;
my $output;
if ($symb =~ m-\.sequence___\d+___ext$-) {
my $exturl = &Apache::lonnet::escape($1);
$output = qq|
<html>
<head><title>$title</title>
</head>
<frameset rows="0,*" border="0">
<frame src=''>
<frame src="$exturl" name="external">
</frameset>
</html>
|;
}
return $output;
}
sub templatedpage {
my ($content_type,$timestamp,$count,$uploads,$udom,$uname) = @_;
my $cdom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
my $cnum = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
my $output = '
<'.$content_type.'>';
my %syllabusdata=();
my %syllabusfields=();
if ($content_type eq 'syllabus') {
%syllabusfields=&Apache::lonlocal::texthash(
'aaa_instructorinfo' => 'Instructor Information',
'bbb_description' => 'Course Description',
'ccc_prereq' => 'Prerequisites',
'cdc_classhours' => 'Class Hours',
'ddd_officehours' => 'Office Hours',
'eee_helproom' => 'Helproom Hours',
'efe_projectinfo' => 'Project Information',
'fff_examinfo' => 'Exam Information',
'fgf_deadlines' => 'Deadlines',
'ggg_grading' => 'Grading Information',
'hhh_readings' => 'Readings',
'iii_coursepack' => 'Coursepack',
'jjj_weblinks' => 'Web Links',
'kkk_textbook' => 'Textbook',
'lll_includeurl' => 'URLs To Include in Syllabus'
);
%syllabusdata = &Apache::lonnet::dump('syllabus',$cdom,$cnum);
} elsif ($content_type eq 'simplepage') {
%syllabusfields=&Apache::lonlocal::texthash(
'aaa_title' => 'Page Title',
'bbb_content' => 'Content',
'ccc_webreferences' => 'Web References'
);
%syllabusdata = &Apache::lonnet::dump('smppage_'.$timestamp,$cdom,$cnum);
} elsif ($content_type eq 'bulletinboard') {
%syllabusfields=&Apache::lonlocal::texthash(
'aaa_title' => 'Topic',
'bbb_content' => 'Task',
'ccc_webreferences' => 'Web References'
);
%syllabusdata = &Apache::lonnet::dump('bulletinpage_'.$timestamp,$cdom,$cnum);
} elsif ($content_type eq 'aboutme') {
%syllabusdata=&Apache::lonnet::dump('aboutme',$udom,$uname);
%syllabusfields=&Apache::lonlocal::texthash(
'aaa_contactinfo' => 'Contact Information',
'bbb_aboutme' => 'About Me',
'ccc_webreferences' => 'Web References'
);
$output .= qq|
<username>$uname</username>
<domain>$udom</domain>
|;
}
foreach (sort keys %syllabusfields) {
$output .= qq|
<$_>
<name>$syllabusfields{$_}</name>
<value>$syllabusdata{$_}</value>
</$_>|;
}
if (defined($syllabusdata{'uploaded.photourl'})) {
if ($syllabusdata{'uploaded.photourl'} =~ m-^/uploaded/$cdom/$cnum/$content_type/(.+)$-) {
push @{$$uploads}, $syllabusdata{'uploaded.photourl'};
}
$output .= '
<photo>
<filename>'.$count.'/'.$1.'</filename>
</photo>';
}
$output .= '
</'.$content_type.'>';
return $output;
}
1;
--raeburn1103810459--