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

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

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