Annotation of loncom/imspackages/imsimport.pm, revision 1.32

1.25      www         1: # The LearningOnline Network with CAPA
                      2: # 
1.32    ! raeburn     3: # $Id: imsimport.pm,v 1.31 2009/05/14 14:24:26 bisitz Exp $
1.25      www         4: #
1.7       raeburn     5: # Copyright Michigan State University Board of Trustees
                      6: #
                      7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      8: #
                      9: # LON-CAPA is free software; you can redistribute it and/or modify
                     10: # it under the terms of the GNU General Public License as published by
                     11: # the Free Software Foundation; either version 2 of the License, or
                     12: # (at your option) any later version.
                     13: #
                     14: # LON-CAPA is distributed in the hope that it will be useful,
                     15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17: # GNU General Public License for more details.
                     18: #
                     19: # You should have received a copy of the GNU General Public License
                     20: # along with LON-CAPA; if not, write to the Free Software
                     21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     22: #
                     23: # /home/httpd/html/adm/gpl.txt
                     24: #
                     25: # http://www.lon-capa.org/
                     26: #
                     27: 
1.1       raeburn    28: package Apache::imsimport;
                     29: 
1.4       raeburn    30: use strict;
                     31: use Apache::Constants qw(:common :http :methods);
                     32: use Apache::loncacc;
                     33: use Apache::loncommon();
                     34: use Apache::lonnet;
1.5       raeburn    35: use Apache::imsprocessor;
1.23      raeburn    36: use Apache::lonlocal;
1.4       raeburn    37: use HTML::Parser;
                     38: use HTML::Entities();
                     39: use Apache::lonlocal;
                     40: use Apache::lonupload;
1.5       raeburn    41: use File::Basename();
1.21      albertel   42: use LONCAPA;
                     43: 
1.5       raeburn    44: # ----------------------------------------------------------------  Jscript One
                     45: sub jscript_one {
1.23      raeburn    46:     my ($fullpath,$jsref,$formname) = @_;
1.14      albertel   47: 
1.20      albertel   48:     my %body_layout = ('rightmargin'  => "0",
                     49: 		       'leftmargin'   => "0",
                     50: 		       'marginwidth'  => "0",
                     51: 		       'topmargin'    => "0",
                     52: 		       'marginheight' => "0");
1.14      albertel   53:     my $start_page = 
                     54: 	&Apache::loncommon::start_page('Create IMS import directory',undef,
                     55: 				       {'only_body'   => 1,
1.20      albertel   56: 					'add_entries' => \%body_layout,
1.14      albertel   57: 					'js_ready'    => 1,});
                     58:     my $end_page = 
                     59: 	&Apache::loncommon::end_page({'js_ready' => 1,});
                     60: 
1.23      raeburn    61:     my %lt = &Apache::lonlocal::texthash( 
                     62:                ddir => 'You must choose a destination directory for the import',
                     63:                cmss => 'You must choose the Course Management System from which the IMS package was exported',
                     64:                loca => 'Location:',
                     65:                newd => 'New Directory',
                     66:                nndi => 'Enter the name of the new directory where you will store the contents of your IMS package.',
                     67:                go => 'Go', 
                     68:              );
1.1       raeburn    69:     $$jsref = <<"END_OF_ONE";
                     70: function verify() {
1.23      raeburn    71:  if ((document.forms.$formname.newdir.value == '')  || (!document.forms.$formname.newdir.value)) {
                     72:    alert('$lt{'ddir'}')
1.1       raeburn    73:    return false
                     74:  }
1.23      raeburn    75:  if (document.forms.$formname.source.selectedIndex == 0) {
                     76:    alert('$lt{'cmss'}');
1.1       raeburn    77:    return false
1.2       raeburn    78:  }
1.1       raeburn    79:  return true
                     80: }
1.2       raeburn    81: 
1.1       raeburn    82: function nextPage() {
1.5       raeburn    83:   if (verify()) {
1.23      raeburn    84:     document.forms.$formname.submit();
1.5       raeburn    85:   }
1.1       raeburn    86: }
                     87: 
                     88: function createWin() {
1.23      raeburn    89:   document.$formname.newdir.value = "";
1.1       raeburn    90:   newWindow = window.open("","CreateDir","HEIGHT=400,WIDTH=750,scrollbars=yes")
                     91:   newWindow.document.open()
1.14      albertel   92:   newWindow.document.write('$start_page')
1.30      bisitz     93:   newWindow.document.write("\\n<img border='0' src='/adm/lonInterFace/author.jpg' alt='[Author Header]' />\\n")
1.23      raeburn    94:   newWindow.document.write("<table border='0' cellspacing='0' cellpadding='0' width='600'>\\n")
1.1       raeburn    95:   newWindow.document.write("<tr><td width='2'>&nbsp;</td><td width='3'>&nbsp;</td>\\n")
1.23      raeburn    96:   newWindow.document.write("<td><h3>$lt{'loca'} <tt>$fullpath</tt></h3><h3>$lt{'newd'}</h3></td></tr>\\n")
1.1       raeburn    97:   newWindow.document.write("<tr><td width='2'>&nbsp;</td><td width='3'>&nbsp;</td>\\n")
                     98:   newWindow.document.write("<td><form name='fileaction' action='/adm/cfile' method='post'>\\n")
1.23      raeburn    99:   newWindow.document.write("$lt{'nndi'}<br /><br />")
1.15      albertel  100:   newWindow.document.write("<input type='hidden' name='filename' value='$fullpath' />")
                    101:   newWindow.document.write("<input type='hidden' name='action' value='newdir' />")
                    102:   newWindow.document.write("<input type='hidden' name='callingmode' value='imsimport' />")
                    103:   newWindow.document.write("$fullpath<input type='text' name='newfilename' value='' />")
1.23      raeburn   104:   newWindow.document.write("<input type='button' value='$lt{'go'}' onClick='document.fileaction.submit();' />")
1.1       raeburn   105:   newWindow.document.write("</td></tr>\\n")
1.14      albertel  106:   newWindow.document.write("</table>")
                    107:   newWindow.document.write('$end_page')
1.1       raeburn   108:   newWindow.document.close()
                    109:   newWindow.focus()
                    110: }
1.2       raeburn   111: 
1.5       raeburn   112: END_OF_ONE
                    113: 
                    114: }
                    115: 
                    116: # ----------------------------------------------------------------  Jscript Two
                    117: sub jscript_two {
                    118:     my ($javascript,$user,$dom,$numcrs) = @_;
                    119:     my %crsentry = ();
                    120:     my $course_list;
                    121:     my $title_list;
                    122:     my @crslist = ();
                    123:     &get_ccroles($user,$dom,\%crsentry,\@crslist);
                    124:     if (@crslist > 0) {
                    125:         $crsentry{$crslist[0]} =~ s/("|,)//g;
                    126:         $title_list = '"'.$crsentry{$crslist[0]}.'"';
                    127:         if (@crslist > 1) {
                    128:             for (my $i=1; $i<@crslist; $i++) {
                    129:                 $crsentry{$crslist[$i]} =~ s/("|,)//g;
                    130:                 $title_list .= ',"'.$crsentry{$crslist[$i]}.'"';
                    131:             }
                    132:         }
                    133:     }
                    134:     $course_list = '"'.join('","',@crslist).'"';
                    135:     $$numcrs = @crslist;
                    136: 
                    137:     $$javascript = qq#
                    138: 
                    139: function checkCourse() {
                    140:   courseID_array = new Array($course_list)
                    141:   courseTitle_array = new Array($title_list)
                    142:   var step2Form = document.forms.pickoptions
                    143:   var conditionType = step2Form.conditions.value
                    144:   var curVal = step2Form.targetcourse.options[step2Form.targetcourse.selectedIndex].value
                    145:   if (curVal == -1) {
                    146:       if ( conditionType == 'both'  )  {
                    147:           if ( step2Form.board.checked == true || step2Form.users.checked == true ) {
                    148:               setCourse(step2Form,'add')
                    149:           }
                    150:       }
                    151:       if ( conditionType == 'users'  )  {
                    152:           if ( step2Form.users.checked == true ) {
                    153:               setCourse(step2Form,'add')
                    154:           }
                    155:       }
                    156:       if ( conditionType == 'board'  )  {
                    157:           if ( step2Form.board.checked == true ) {
                    158:               setCourse(step2Form,'add')
                    159:           }
                    160:       }
                    161:   }
                    162:   else { 
                    163:       if ( conditionType == 'both'  )  {
                    164:           if ( step2Form.board.checked == false && step2Form.users.checked == false ) {
                    165:               setCourse(step2Form,'clear')
                    166:           }
                    167:       }
                    168:       if ( conditionType == 'users'  )  {
                    169:           if ( step2Form.users.checked == false ) {
                    170:               setCourse(step2Form,'clear')
                    171:           }
                    172:       }
                    173:       if ( conditionType == 'board'  )  {
                    174:           if ( step2Form.board.checked == false ) {
                    175:               setCourse(step2Form,'clear')
                    176:           }
                    177:       }
                    178:   }
                    179: }
                    180: 
                    181: function setCourse(step2Form,call) {
                    182:     step2Form.targetcourse.length = 0
                    183:     if (call == 'add') {
                    184:         step2Form.targetcourse.length = 0
                    185:         step2Form.targetcourse.options[0] = new Option("Please Select","0",true,true)
                    186:         for (var i=0; i<courseID_array.length; i++) {
                    187:             step2Form.targetcourse.options[i+1] = new Option(courseTitle_array[i],courseID_array[i],false,false)
                    188:         }
                    189:         step2Form.targetcourse.selectedIndex = 0
                    190:     }
                    191:     else {
                    192:         step2Form.targetcourse.options[0] = new Option("Not required","-1",true,true)
                    193:         step2Form.targetcourse.selectedIndex = 0
                    194:     }
                    195: }
                    196: 
                    197: 
                    198: function setOptions(caller,itemnum) {
                    199:   var numCrs = $$numcrs
                    200:   var opForm = document.forms.pickoptions
                    201:   var menu = 1 + itemnum*2
                    202:   opForm.elements[menu].length = 0
                    203:   if (opForm.elements[itemnum*2].checked == true) {
                    204:     if (caller == "board") {
                    205:       opForm.elements[menu].options[0] = new Option("Select","-1",true,true)
                    206:       opForm.elements[menu].options[1] = new Option("Import topics only","topics",true,true)
                    207:       opForm.elements[menu].options[2] = new Option("Import topics + posts (with author)","allpost",true,true)
                    208:       opForm.elements[menu].options[3] = new Option("Import topics + posts (no author)","allanon",true,true)
                    209:     }
                    210:     else { 
                    211:       if (caller == "users") {
                    212:         opForm.elements[menu].length = 0
                    213:         opForm.elements[menu].options[0] = new Option("Select","-1",true,true)
                    214:         opForm.elements[menu].options[1] = new Option("Enroll students only","students",true,true)
                    215:         opForm.elements[menu].options[2] = new Option("Enroll all users","all",true,true)
                    216:       }
                    217:     }
                    218:   }
                    219:   else {
                    220:     opForm.elements[menu].options[0] = new Option("Not required","0",true,true)
                    221:   }
                    222:   opForm.elements[menu].selectedIndex = 0
                    223:   if (numCrs > 0) {
                    224:       checkCourse()
                    225:   }
                    226: }
                    227: 
                    228: function verify(caller) {
                    229:   var numCrs = $$numcrs
                    230:   var opForm = document.forms.pickoptions
                    231:   var totcheck = 0;
                    232:   var totchg = 0;
                    233:   for (var i=0; i<caller; i++) {
                    234:     if (opForm.elements[2*i].checked == true) {
                    235:       totcheck ++
                    236:       if (opForm.elements[2*i].name == "board") { 
                    237:         if (opForm.elements[2*i+1].selectedIndex == 0) {     
                    238:           alert("You must select one of the additional options when importing Discussion Boards ")
                    239:           return false
                    240:         }
                    241:         if (numCrs == 0) {
                    242:             opForm.elements[2*i].checked = false
                    243:             totchg ++
                    244:         }
                    245:         else {
                    246:           if (opForm.targetcourse.selectedIndex == 0) {
                    247:             alert("You must select a target course when importing Discussion Boards")
                    248:             return false
                    249:           }
                    250:         }
                    251:       }
                    252:       if (opForm.elements[2*i].name == "users") {
                    253:         if (opForm.elements[2*i+1].selectedIndex == 0) {     
                    254:           alert("You must select one of the additional options when importing Enrollment")
                    255:           return false
                    256:         }
                    257:         if (numCrs == 0) {
                    258:             opForm.elements[2*i].checked = false
                    259:             totchg ++ 
                    260:         }
                    261:         else {
                    262:           if (opForm.targetcourse.selectedIndex == 0) {
                    263:             alert("You must select a target course when importing enrollment information")
                    264:             return false
                    265:           }
                    266:         }
                    267:       }
                    268:     }
                    269:   }
                    270:   if (totcheck == 0) {
                    271:     alert("You must check the Checkbox for at least one Content Type");
                    272:     return false
                    273:   }
                    274:   return true
                    275: }
                    276: 
                    277: function nextPage(caller) {
                    278:   if (verify(caller)) {
                    279:     document.forms.pickoptions.submit()
                    280:   }
1.2       raeburn   281: }
                    282: 
1.5       raeburn   283: #;
                    284: 
                    285: }
1.1       raeburn   286: 
1.5       raeburn   287: # ----------------------------------------------------------------  Jscript Three
                    288: sub jscript_three {
                    289:     my $javascript = shift;
1.1       raeburn   290: }
                    291: 
1.5       raeburn   292: # ---------------------------------------------------------------- Display One
                    293: sub display_one {
1.23      raeburn   294:     my ($r,$uname,$fn,$fullpath,$formname) = @_;
                    295:     $r->print('<form name="'.$formname.'" method="post">'.
                    296:               &Apache::lonhtmlcommon::topic_bar(1,&mt('Specify the Course Management system used to create the package')).
                    297:         &mt('Choose the CMS used to create your IMS content package.').'&nbsp;&nbsp;
1.2       raeburn   298:         <select name="source">
1.27      bisitz    299:          <option value="-1" selected="selected">Please select</option>
1.23      raeburn   300:          <option value="bb5">Blackboard 5</option>
                    301:          <option value="bb6">Blackboard 6</option>
1.32    ! raeburn   302:          <option value="angel5">ANGEL 5.5</option>
1.23      raeburn   303:          <option value="webctce4">WebCT 4 Campus Edition</option>
                    304:          <option value="webctvista4">WebCT Vista 4</option>
                    305:         </select><br />'."\n".
                    306:         &Apache::lonhtmlcommon::topic_bar(2,&mt('Create a directory where you will unpack your IMS package'))."\n".
                    307:          &mt('Create a destination LON-CAPA directory in which to store the contents of the IMS package file.').'&nbsp;&nbsp;<input type="button" name="createdir" value="Create Directory" onClick="javascript:createWin()" /><input type="hidden" name="newdir" value="" /><br /><br />
                    308:           <input type="hidden" name="uploaduname" value="'.$uname.'" />
                    309:           <input type="hidden" name="filename" value="'.$fn.'" />
1.15      albertel  310:           <input type="hidden" name="phase" value="three" />
1.23      raeburn   311:           <input type="button" name="nextpage" value="'.&mt('Proceed').'" onClick="javascript:nextPage();" />&nbsp;&nbsp;&nbsp;&nbsp;
                    312:           <input type="button" name="exitpage" value="'.&mt('Exit now').'" onClick="javascript:location.href='."'$fullpath'".'" />
                    313:          </form>');
1.5       raeburn   314: }
                    315: 
                    316: # ---------------------------------------------------------------- Display Two
                    317: sub display_two {
                    318:     my ($r,$zipupload,$areas,$areaname,$cmsmap,$uname,$newdir,$numcrs,$fullpath) = @_;
                    319:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['folder','source']);
1.11      albertel  320:     my $cms = $env{'form.source'};
                    321:     my $dirname = $env{'form.newdir'};
1.5       raeburn   322:     my $tempdir = &Apache::imsprocessor::create_tempdir('CSTR',$dirname,'');
                    323:     my $fname = &Apache::imsprocessor::uploadzip('CSTR',$tempdir,$zipupload);
                    324:     my $unzip_result = '';
                    325:     my $manifest_result = '';
                    326:     unless ($tempdir eq '') {
                    327:         $unzip_result = &Apache::imsprocessor::expand_zip($tempdir,$fname);
                    328:     }
                    329:     my %resources = ();
1.9       raeburn   330:     my %includedres = ();
                    331:     my %includeditems = ();
1.5       raeburn   332:     my %items = ();
                    333:     my %hrefs = ();
                    334:     my %resinfo = ();
                    335:     my %count = ();
1.23      raeburn   336: 
                    337:     my %lt = &Apache::lonlocal::texthash(
                    338:                   cont => 'Choose which content types you wish to import',
                    339:                   impo => 'Import',
                    340:                   type => 'Content type',
                    341:                   addo => 'Additional options',
                    342:                   chec => 'Check Import first',
                    343:                   bbus => 'Choose a course to receive bulletin boards and user enrollment',
                    344:                   list => 'A listing of possible course targets will be displayed if import of bulletin boards and/or enrollment is checked above (step 3). If you do not plan to import either of these content types, there is no need to specify a course.',
                    345:                   chco => 'Choose course:',
                    346:                   nreq => 'Not required',
                    347:                   yodo => 'You do not have active course coordinator status in any LON-CAPA courses currently, so bulletin boards and enrollment information included in your IMS package will be discarded, regardless of your import choice for these two items above (step 3).',
                    348:                   ifyo => "If you wish to import bulletin boards and/or user information into LON-CAPA please click 'Exit now' to quit the current IMS import process, and contact your domain coordinator and request a course coordinator role in a LON-CAPA course into which you can upload bulletin boards and/or enroll users.",
                    349:                   impa => 'Import package',
                    350:                   unpa => 'Unpacking of your IMS package failed because an IMS manifest file was not located in the package',
                    351:                   proc => 'Processing of your IMS package failed because the file you uploaded could not be unzipped',
                    352:                   exit => 'Exit now',
                    353:     );
1.5       raeburn   354: 
                    355:     my $counter = 0;
                    356:     my $iter = 0;
                    357:     my %count = (
                    358:                 announce => 0,
                    359:                 board => 0,
                    360:                 doc => 0,
                    361:                 extlink => 0,
                    362:                 msg => 0,
                    363:                 pool => 0,
                    364:                 quiz => 0,
                    365:                 staff => 0,
                    366:                 survey => 0,
                    367:                 users => 0,
                    368:                 );
                    369:     my $conditions;
                    370:     if ($unzip_result eq 'ok') {
1.19      raeburn   371:         $manifest_result = &Apache::imsprocessor::process_manifest($cms,
                    372:                             $tempdir,\%resources,\%items,\%hrefs,\%resinfo,
                    373:                             'choose',\%includedres,\%includeditems);
1.5       raeburn   374:         if ($manifest_result eq 'ok') {
                    375:             foreach my $res (sort keys %resources) {
1.19      raeburn   376:                 if ($cms eq 'bb5' || $cms eq 'bb6' || $cms eq 'webctce4' 
                    377:                     || $cms eq 'webctvista4') {
1.5       raeburn   378:                     foreach my $area (keys %{$$cmsmap{$cms}}) {
                    379:                         if ($resources{$res}{type} eq $$cmsmap{$cms}{$area}) {
                    380:                             $count{$area} ++;
                    381:                         }
                    382:                     }
1.32    ! raeburn   383:                 } elsif ($cms eq 'angel5') {
1.5       raeburn   384:                     foreach my $area (keys %{$$cmsmap{$cms}}) {
                    385:                         if ($area eq 'doc') {
                    386:                             if (grep/^$resources{$res}{type}$/,@{$$cmsmap{$cms}{doc}}) {
                    387:                                 $count{$area} ++;
                    388:                             }
                    389:                         } elsif ($resources{$res}{type} eq $$cmsmap{$cms}{$area}) {
                    390:                             $count{$area} ++;                                
                    391:                         }
                    392:                     }
                    393:                 }
                    394:             }
                    395:             if ($count{board} > 0) {
                    396:                 if ($count{users} > 0) {
                    397:                     $conditions = 'both';
                    398:                 } else {
                    399:                     $conditions = 'board';
                    400:                 }
                    401:             } elsif ($count{users} > 0) {
                    402:                 $conditions = 'users';
                    403:             } else {
                    404:                 $conditions = 'none';
                    405:             }
                    406: 
1.23      raeburn   407:             $r->print('<form name="pickoptions" method="post">'.
                    408:                       &Apache::lonhtmlcommon::topic_bar(3,$lt{'cont'}).
                    409:                       &Apache::loncommon::start_data_table().
                    410:                       &Apache::loncommon::start_data_table_header_row().
1.24      raeburn   411:                       '<th>'.$lt{'impo'}.'</th><th>'.$lt{'type'}.'</th><th>'.
1.23      raeburn   412:                       $lt{'addo'}.'</th>'.
                    413:                       &Apache::loncommon::end_data_table_header_row());
1.5       raeburn   414:             foreach my $area (@{$areas}) {
                    415:                 if ($count{$area} > 0) {
                    416:                     my $count_tag = 'flag_'.$counter;
1.23      raeburn   417:                     $r->print(&Apache::loncommon::start_data_table_row()."\n".
                    418:                               '<td><input name="'.$area.'" type="checkbox" ');
1.5       raeburn   419:                     if ($area eq 'board' || $area eq 'users') {
1.23      raeburn   420:                         $r->print('onClick="javascript:setOptions('."'$area','$counter'".');" ');
1.5       raeburn   421:                     }
1.23      raeburn   422:                     $r->print('/></td>'.
                    423:                               '<td>&nbsp;&nbsp;'.$$areaname{$area}.'&nbsp;&nbsp; - '.
                    424:                               &mt('[quant,_1,item]',$count{$area}).'</td>');
1.5       raeburn   425:                     if ($area eq 'board') {
1.23      raeburn   426:                         $r->print('<td>&nbsp;&nbsp;
                    427:                  <select name="db_handling">
                    428:                   <option value="-2">&lt;-- '.$lt{'chec'}.'</option>
                    429:                  </select>
                    430:                 </td>');
1.5       raeburn   431:                     } elsif ($area eq 'users') {
1.23      raeburn   432:                         $r->print('<td>&nbsp;&nbsp;
                    433:                  <select name="user_handling">
                    434:                   <option value="-2">&lt;-- '.$lt{'chec'}.'</option>
1.2       raeburn   435:                  </select>
1.23      raeburn   436:                 </td>');
1.5       raeburn   437:                     } else {
1.23      raeburn   438:                         $r->print('<td>&nbsp;&nbsp;'.&mt('None')."\n".
                    439:                                   '<input type="hidden" name="'.$count_tag.'" /></td>');
1.5       raeburn   440:                     }
                    441:                     $counter ++;
1.23      raeburn   442:                     $r->print(&Apache::loncommon::end_data_table_row());
1.5       raeburn   443:                 }
                    444:             }
1.23      raeburn   445:             $r->print(&Apache::loncommon::end_data_table());
1.5       raeburn   446:             if ($count{board} + $count{users} > 0) {
1.23      raeburn   447:                 $r->print(&Apache::lonhtmlcommon::topic_bar(4,$lt{'bbus'}));
1.5       raeburn   448:                 if ($$numcrs > 0) {
1.23      raeburn   449:                     $r->print($lt{'list'}.'<br /><br />'.$lt{'chco'}.'&nbsp;&nbsp;'."\n".
                    450:                               '<select name="targetcourse">
                    451:                                 <option value="-1">'.$lt{'nreq'}.'</option>
                    452:                                </select>');
1.5       raeburn   453:                 } else {
1.23      raeburn   454:                     $r->print($lt{'yodo'}.' '.$lt{'ifyo'});
                    455:                 }
                    456:             }
                    457:             $r->print('<br /><br />
                    458:           <input type="hidden" name="newdir" value="'.$env{'form.newdir'}.'" />
                    459:           <input type="hidden" name="conditions" value="'.$conditions.'" />
                    460:           <input type="hidden" name="source" value="'.$cms.'" />
                    461:           <input type="hidden" name="tempdir" value="'.$tempdir.'" />
1.28      bisitz    462:           <input type="hidden" name="uploaduname" value="'.$uname.'" />
                    463:           <input type="hidden" name="filename" value="'.$fname.'" />
1.23      raeburn   464:           <input type="hidden" name="phase" value="four" />'."\n");
1.5       raeburn   465:             if ($count{board} == 0) {
1.23      raeburn   466:                 $r->print('<input type="hidden" name="board" value="" />'."\n");
1.5       raeburn   467:             }
                    468:             if ($count{users} == 0) {
1.23      raeburn   469:                 $r->print('<input type="hidden" name="users" value="" />'."\n");
1.5       raeburn   470:             }
1.23      raeburn   471:             $r->print('<input type="button" name="nextpage" value="'.$lt{'impa'}.'" onClick="javascript:nextPage('."'$counter.'".')" />&nbsp;&nbsp;&nbsp;
                    472:            <input type="button" name="exitpage" value="'.$lt{'exit'}.'" onClick="javascript:location.href='."'$fullpath'".'" /></form>');
1.5       raeburn   473:         } else {
1.23      raeburn   474:             $r->print($lt{'unpa'});
1.2       raeburn   475:         }
1.4       raeburn   476:     } else {
1.23      raeburn   477:         $r->print($lt{'proc'});
1.5       raeburn   478:     }
                    479: }
1.1       raeburn   480: 
1.5       raeburn   481: # ---------------------------------------------------------------- Display Three
                    482: sub display_three {
                    483:     my ($r,$uname,$udom,$areas,$areaname,$cmsmap,$destdir,$newdir) = @_;
                    484:     my $crs = '';
                    485:     my $cdom = '';
                    486:     my $db_handling = '';
                    487:     my $timenow = time; 
                    488:     my $announce_handling = 'ok';
1.11      albertel  489:     my $cms = $env{'form.source'};
                    490:     if ( defined($env{'form.bb_crs'}) ) {
                    491:         ($cdom,$crs) = split/\//,$env{'form.bb_crs'};
1.4       raeburn   492:     } 
1.5       raeburn   493:     my $user_crs = '';
                    494:     my $user_cdom = '';
                    495:     my $user_handling = '';
1.11      albertel  496:     if ( defined($env{'form.user_crs'}) ) {
                    497:         ($user_cdom,$user_crs) = split/\//,$env{'form.user_crs'};
1.5       raeburn   498:     }
                    499:     my $seqstem = "/res/$udom/$uname/$newdir";
1.9       raeburn   500:     my %importareas = ();
                    501:     my %includedres = ();
                    502:     my %includeditems = ();
1.10      raeburn   503:     my %randompicks = ();
1.5       raeburn   504:     my @targets = ();
                    505:     my %resources = ();
                    506:     my %items = ();
                    507:     my %hrefs = ();
                    508:     my %urls = ();
                    509:     my %resinfo = ();
                    510:     my %total = (
                    511:                    page => 0,
                    512:                    prob => 0,
                    513:                    seq => 0,
                    514:                    board => 0,         
                    515:                    quiz => 0,
                    516:                    surv => 0,
1.23      raeburn   517:                    file => 0,
1.5       raeburn   518:     );
                    519: 
                    520:     my @pages = ();
                    521:     my @sequences = ();
                    522:     my @resrcfiles = ();
1.19      raeburn   523:     my @assessmentfiles = ();
1.5       raeburn   524: 
1.11      albertel  525:     my $tempdir = $env{'form.tempdir'};
1.5       raeburn   526: 
                    527:     foreach my $area (@{$areas}) {
1.11      albertel  528:         if (defined($env{"form.$area"}) ) {
1.32    ! raeburn   529:             if ($cms eq 'angel5' && $area eq 'doc') {
1.5       raeburn   530:                 foreach (@{$$cmsmap{$cms}{$area}}) {
1.9       raeburn   531:                     $importareas{$_} = 1;
1.1       raeburn   532:                 }
1.5       raeburn   533:             } else {
1.9       raeburn   534:                 $importareas{$$cmsmap{$cms}{$area}} = 1;
1.2       raeburn   535:             }
1.5       raeburn   536:             if ($area eq 'board') {
1.11      albertel  537:                 $db_handling = $env{'form.db_handling'};
1.5       raeburn   538:             } elsif ($area eq 'users') {
1.11      albertel  539:                 $user_handling = $env{'form.user_handling'};
1.4       raeburn   540:             }
1.1       raeburn   541:         }
                    542:     }
1.9       raeburn   543: 
1.23      raeburn   544:     my %lt = &Apache::lonlocal::texthash (
                    545:                  yims => 'Your IMS package has been processed successfully.',
                    546:                  plsv => 'Please view the imported items and use the LON-CAPA editing tools to make changes.',
                    547:                  tseq => "The sequences directory contains a file named 'Top.sequence' which includes links to the items found at the top level of your IMS package. From there you can follow links to display all the imported items. Alternatively, you can browse the pages, sequences, problems and resfiles directories directly. Note if you rename a file, you will need to modify any .sequence files or .page files which include a reference to the renamed file.",
                    548:                  tfin => 'The final step in the IMS import process is to publish the materials you have imported into your Construction Space so that you can use them in a course. Once your files are published, subsequent re-publication will result in the storage of information about changes between the different versions.',
                    549:                  disp => 'Display new directory',
                    550:                  proc => 'Processing of your IMS package failed, because the IMS content package did not contain an IMS manifest file.'
                    551:              );
1.19      raeburn   552:     my $manifest_result = &Apache::imsprocessor::process_manifest($cms,$tempdir,
                    553:                           \%resources,\%items,\%hrefs,\%resinfo,'prepare',
                    554:                           \%includedres);
1.9       raeburn   555:     if ($manifest_result eq 'ok') {
                    556:         foreach my $res (sort keys %resources) {
                    557:             if ($importareas{$resources{$res}{type}}) {
                    558:                 $includedres{$res} = 1;
1.19      raeburn   559:                 if ($resources{$res}{type} eq 'webct.manifest' || 
                    560:                      $resources{$res}{type} eq 'webct.assessment' ||
                    561:                      $resources{$res}{type} eq 'webct.question') {
                    562:                     push(@assessmentfiles,$res);
                    563:                 }   
1.9       raeburn   564:             }
                    565:         }
                    566:         foreach my $itm (sort keys %items) {
                    567:             &Apache::imsprocessor::get_imports(\%includeditems,\%items,\%resources,\%importareas,$itm);
                    568:         }
                    569:     }
                    570: 
                    571:     foreach my $itm (sort keys %includeditems) {
                    572:         &Apache::imsprocessor::get_parents(\%includeditems,\%items,$itm);
                    573:     }
                    574: 
1.19      raeburn   575:     $manifest_result = &Apache::imsprocessor::process_manifest($cms,$tempdir,
                    576:                        \%resources,\%items,\%hrefs,\%resinfo,'build',
                    577:                        \%includedres,\%includeditems);
1.5       raeburn   578:     if ($manifest_result eq 'ok') {
1.9       raeburn   579:         &Apache::imsprocessor::target_resources(\%resources,\%importareas,\@targets);
1.5       raeburn   580: 
                    581:         my @boards = ();
                    582:         my @announcements = ();
                    583:         my @quizzes = ();
                    584:         my @surveys = ();
1.9       raeburn   585:         my @pools = ();
1.5       raeburn   586:         my @groups = ();
                    587:         my %messages = ();
                    588:         my @timestamp = ();
                    589:         my %boardnum = ();
                    590:         my @topurls = ();
                    591:         my @topnames = ();
1.7       raeburn   592:         my @packages = ();
1.5       raeburn   593: 
1.10      raeburn   594:         &Apache::imsprocessor::process_resinfo($cms,'CSTR',$tempdir,$destdir,\%items,\%resources,\@targets,\@boards,\@announcements,\@quizzes,\@surveys,\@pools,\@groups,\%messages,\@timestamp,\%boardnum,\%resinfo,$udom,$uname,$cdom,$crs,$db_handling,$user_handling,\%total,$seqstem,$seqstem,\@resrcfiles,\@packages,\%hrefs,\@pages,\@sequences,\%randompicks);
1.7       raeburn   595: 
1.23      raeburn   596:         my $copy_result = &Apache::imsprocessor::copy_resources('CSTR',$cms,\%hrefs,$tempdir,\@targets,\%urls,$crs,$cdom,$destdir,$timenow,\@assessmentfiles,\%total);
1.5       raeburn   597:    
1.10      raeburn   598:         &Apache::imsprocessor::build_structure($cms,'CSTR',$destdir,\%items,\%resinfo,\%resources,\@targets,\%hrefs,$udom,$uname,$newdir,$timenow,$cdom,$crs,\@timestamp,\%total,\@boards,\@announcements,\@quizzes,\@surveys,\@pools,\%boardnum,\@pages,\@sequences,\@topurls,\@topnames,\@packages,\%includeditems,\%randompicks);
1.5       raeburn   599: 
1.9       raeburn   600:         $r->print("<h3>IMS import completed</h3>");
1.5       raeburn   601: 
1.32    ! raeburn   602:         if ($cms eq 'angel5') {
1.23      raeburn   603:             $r->print($lt{'yims'}.' '.&mt('A total of [quant,_1,sequence], [quant,_2,composite page], and [quant,_3,bulletin board] have been created, and [quant,_4,file] copied.',$total{seq},$total{page},$total{board},$total{file})."\n");
                    604:         } else {
                    605:             $r->print($lt{'yims'}.' '.&mt('A total of [quant,_1,sequence], [quant,_2,composite page], [quant,_3,bulletin board], [quant,_4,quiz,quizzes], [quant,_5,survey], and [quant,_6,problem] have been created, and [quant,_7,file] copied.',$total{seq},$total{page},$total{board},$total{quiz},$total{surv},$total{prob},$total{file})."\n");
1.5       raeburn   606:         }
1.23      raeburn   607:         $r->print('<br /><br />'.$lt{'plsv'}.' '.$lt{'tseq'}.'<br /><br />'.$lt{'tfin'}.'<br /><br /><a href="/priv/'.$uname.'/'.$newdir.'">'.$lt{'disp'}.'</a>');
                    608:         if ($destdir =~ m-^/home/$uname/public_html/-) {
1.9       raeburn   609:             system (" rm -r -f $destdir/temp");
                    610:         }
1.5       raeburn   611:     } elsif ($manifest_result eq 'nomanifest') {
1.23      raeburn   612:         $r->print($lt{'proc'});
1.4       raeburn   613:     }
1.5       raeburn   614: }
                    615: 
                    616: # ---------------------------------------------------------------- Get LON-CAPA Course Coordinator roles for this user
                    617: sub get_ccroles {
                    618:     my ($user,$dom,$crsentry,$crslist) = @_;
                    619:     my %roles = ();
                    620:     unless ($user eq '') {
                    621:         %roles = &Apache::lonnet::dump('roles',$dom,$user);
1.4       raeburn   622:     }
1.5       raeburn   623:     my $iter = 0;
                    624:     my @codes = ();
                    625:     my %courses = ();
                    626:     my @crslist = ();
                    627:     my %descrip =();
                    628:     foreach my $key (keys %roles ) {
1.21      albertel  629:         if ($key =~ m{^/($LONCAPA::domain_re)/($LONCAPA::username_re)_cc$}) {
1.5       raeburn   630:             my $cdom = $1;
                    631:             my $crs = $2;
                    632:             my $role_end = 0;
                    633:             my $role_start = 0;
                    634:             my $active_chk = 1;
                    635:             if ( $roles{$key} =~ m/^cc_(\d+)/ ) {
                    636:                 $role_end = $1;
                    637:                 if ( $roles{$key} =~ m/^cc_($role_end)_(\d+)$/ )
                    638:                 {
                    639:                     $role_start = $2;
                    640:                 }
                    641:             }
                    642:             if ($role_start > 0) {
                    643:                 if (time < $role_start) {
                    644:                     $active_chk = 0;
1.1       raeburn   645:                 }
1.5       raeburn   646:             }
                    647:             if ($role_end > 0) {
                    648:                 if (time > $role_end) {
                    649:                     $active_chk = 0;
1.1       raeburn   650:                 }
                    651:             }
1.5       raeburn   652:             if ($active_chk) {
                    653:                 my $currcode = '';
                    654:                 my %settings = &Apache::lonnet::get('environment',['internal.coursecode','description'],$cdom,$crs);
                    655:                 if (defined($settings{'description'}) ) {
                    656:                     $descrip{$crs} = $settings{'description'};
1.1       raeburn   657:                 } else {
1.5       raeburn   658:                     $descrip{$crs} = 'Unknown';
1.1       raeburn   659:                 }
1.5       raeburn   660:                 if (defined($settings{'internal.coursecode'}) ) {
                    661:                     $currcode = $settings{'internal.coursecode'};
                    662:                     if ($currcode eq '') {
                    663:                         $currcode = "____".$iter;
                    664:                         $iter ++;
1.1       raeburn   665:                     }
                    666:                 } else {
1.5       raeburn   667:                     $currcode = "____".$iter;
                    668:                     $iter ++;
                    669:                 }
                    670:                 unless (grep/^$currcode$/,@codes) {
                    671:                     push @codes,$currcode;
                    672:                     @{$courses{$currcode}} = ();
1.1       raeburn   673:                 }
1.5       raeburn   674:                 push @{$courses{$currcode}}, $cdom.'/'.$crs;
1.1       raeburn   675:             }
1.5       raeburn   676:         }
                    677:     }
                    678:     foreach my $code (sort @codes) {
                    679:         foreach my $crsdom (@{$courses{$code}}) {
1.2       raeburn   680:             my ($cdom,$crs) = split/\//,$crsdom;
                    681:             my $showcode = '';
                    682:             unless ($code =~m/^____\d+$/) {  $showcode = $code; }
                    683:             $$crsentry{$crsdom} = $showcode.':'.$descrip{$crs};
1.5       raeburn   684:             push @{$crslist}, $crsdom;
1.2       raeburn   685:         }
                    686:     }
1.5       raeburn   687:     return;
1.2       raeburn   688: }
1.1       raeburn   689: 
                    690: # ---------------------------------------------------------------- Main Handler
                    691: sub handler {
                    692:     my $r=shift;
                    693:     my $uname;
                    694:     my $udom;
                    695:     my $javascript = '';
                    696:     my $page_name = '';
                    697:     my $current_page = '';
                    698:     my $qcount = '';
1.5       raeburn   699: 
                    700: # get personal information for this user
1.11      albertel  701:     my $user=$env{'user.name'};
                    702:     my $dom=$env{'user.domain'};
1.5       raeburn   703: 
1.1       raeburn   704: #
1.5       raeburn   705: # re-attach user
1.1       raeburn   706: #
1.11      albertel  707:     if ($env{'form.uploaduname'}) {
                    708:         $env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'.
                    709:             $env{'form.filename'};
1.1       raeburn   710:     }
                    711:     ($uname,$udom)=
1.11      albertel  712:         &Apache::loncacc::constructaccess($env{'form.filename'},
1.1       raeburn   713:                                           $r->dir_config('lonDefDomain'));
                    714:     unless (($uname) && ($udom)) {
                    715:         $r->log_reason($uname.' at '.$udom.
1.11      albertel  716:                        ' trying to publish file '.$env{'form.filename'}.
1.1       raeburn   717:                        ' - not authorized',
                    718:                        $r->filename);
                    719:         return HTTP_NOT_ACCEPTABLE;
                    720:     }
                    721:                                                                                              
                    722:     my $fn;
1.11      albertel  723:     if ($env{'form.filename'}) {
                    724:         $fn=$env{'form.filename'};
1.26      raeburn   725:         $fn=~s/^https?\:\/\/[^\/]+\///;
1.1       raeburn   726:         $fn=~s/^\///;
1.22      albertel  727:         $fn=~s/(\~|priv\/)($LONCAPA::username_re)//;
1.1       raeburn   728:         $fn=~s/\/+/\//g;
                    729:     } else {
1.11      albertel  730:         $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
1.1       raeburn   731:                        ' unspecified filename for upload', $r->filename);
                    732:         return HTTP_NOT_FOUND;
                    733:     }
1.5       raeburn   734:     my $zipupload = '/home/'.$uname.'/public_html'.$fn;
1.1       raeburn   735:     my $pathname = &File::Basename::dirname($fn);
                    736:     my $fullpath = '/priv/'.$uname.$pathname;
                    737:     unless ($pathname eq '/') {
                    738:         $fullpath .= '/';
                    739:     }
1.5       raeburn   740: 
                    741:     my @areas = ();
                    742:     my %cmsmap = ();
                    743:     my %areaname = ();
                    744:     my $numcrs = 0;
                    745:              
                    746:     &Apache::imsprocessor::ims_config(\@areas,\%cmsmap,\%areaname);
1.1       raeburn   747: # ----------------------------------------------------------- Start page output
                    748:     &Apache::loncommon::content_type($r,'text/html');
                    749:     $r->send_http_header;
1.5       raeburn   750: 
1.23      raeburn   751:     my $formname_one = 'info';
1.11      albertel  752:     if ($env{'form.phase'} eq 'two') {
1.23      raeburn   753:         &jscript_one($fullpath,\$javascript,$formname_one);
1.11      albertel  754:     } elsif ($env{'form.phase'} eq 'three') {
1.5       raeburn   755:         &jscript_two(\$javascript,$user,$dom,\$numcrs);
1.11      albertel  756:     } elsif ($env{'form.phase'} eq 'four') {
1.5       raeburn   757:         &jscript_three(\$javascript);
1.1       raeburn   758:     }
1.14      albertel  759:     $javascript = "<script type=\"text/javascript\">\n//<!--\n$javascript\n// --></script>\n";
                    760: 
                    761:     my $title = 'Upload IMS package to Construction Space';
1.20      albertel  762:     $r->print(&Apache::loncommon::start_page($title, $javascript));
1.14      albertel  763: 
1.11      albertel  764:     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
1.31      bisitz    765:         $r->print('<p><span class="LC_warning">'
                    766:                   .&mt('Co-Author [_1]',$uname.':'.$udom)
                    767:                   .'</span></p>'
1.29      bisitz    768:         );
1.5       raeburn   769:     }   
1.11      albertel  770:     if ($env{'form.phase'} eq 'two') {
1.1       raeburn   771:         my $flag = &Apache::lonupload::phasetwo($r,$fn,$uname,$udom,'imsimport');
                    772:         if ($flag eq 'ok') {
1.23      raeburn   773:             &display_one($r,$uname,$fn,$fullpath,$formname_one);
1.5       raeburn   774:         }
1.11      albertel  775:     } elsif ( ($env{'form.phase'} eq 'three') || ($env{'form.phase'} eq 'four') ) {
                    776:         my $docroot = $env{'form.newdir'};
1.5       raeburn   777:         my $newdir = '';
                    778:         if ($docroot =~ m|public_html/(.+)$|) {
                    779:             $newdir = $1;
                    780:         }
1.11      albertel  781:         if ($env{'form.phase'} eq 'three') {
1.5       raeburn   782:             &display_two ($r,$zipupload,\@areas,\%areaname,\%cmsmap,$uname,$newdir,\$numcrs,$fullpath);
1.11      albertel  783:         } elsif ($env{'form.phase'} eq 'four') {
1.5       raeburn   784:             &display_three ($r,$uname,$udom,\@areas,\%areaname,\%cmsmap,$docroot,$newdir);
1.1       raeburn   785:         }
                    786:     } else {
                    787:         &Apache::lonupload::phaseone($r,$fn,$uname,$udom,'imsimport');
                    788:     }
1.14      albertel  789:     $r->print(&Apache::loncommon::end_page());
1.1       raeburn   790:     return OK;
                    791: }
                    792: 1;
                    793: __END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>