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

1.25      www         1: # The LearningOnline Network with CAPA
                      2: # 
1.36    ! raeburn     3: # $Id: imsimport.pm,v 1.35 2011/10/24 22:02:38 www 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.36    ! raeburn    46:     my ($fullpath,$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.36    ! raeburn    69:     return <<"END_OF_ONE";
1.1       raeburn    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 {
1.36    ! raeburn   118:     my ($user,$dom,$numcrs) = @_;
1.5       raeburn   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: 
1.36    ! raeburn   137:     return <<"END_OF_TWO";
1.5       raeburn   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.36    ! raeburn   283: END_OF_TWO
1.5       raeburn   284: 
                    285: }
1.1       raeburn   286: 
1.5       raeburn   287: # ---------------------------------------------------------------- Display One
                    288: sub display_one {
1.36    ! raeburn   289:     my ($r,$fn,$fullpath,$formname) = @_;
1.23      raeburn   290:     $r->print('<form name="'.$formname.'" method="post">'.
                    291:               &Apache::lonhtmlcommon::topic_bar(1,&mt('Specify the Course Management system used to create the package')).
                    292:         &mt('Choose the CMS used to create your IMS content package.').'&nbsp;&nbsp;
1.2       raeburn   293:         <select name="source">
1.27      bisitz    294:          <option value="-1" selected="selected">Please select</option>
1.23      raeburn   295:          <option value="bb5">Blackboard 5</option>
                    296:          <option value="bb6">Blackboard 6</option>
1.32      raeburn   297:          <option value="angel5">ANGEL 5.5</option>
1.23      raeburn   298:          <option value="webctce4">WebCT 4 Campus Edition</option>
                    299:          <option value="webctvista4">WebCT Vista 4</option>
                    300:         </select><br />'."\n".
                    301:         &Apache::lonhtmlcommon::topic_bar(2,&mt('Create a directory where you will unpack your IMS package'))."\n".
                    302:          &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 />
                    303:           <input type="hidden" name="filename" value="'.$fn.'" />
1.15      albertel  304:           <input type="hidden" name="phase" value="three" />
1.23      raeburn   305:           <input type="button" name="nextpage" value="'.&mt('Proceed').'" onClick="javascript:nextPage();" />&nbsp;&nbsp;&nbsp;&nbsp;
                    306:           <input type="button" name="exitpage" value="'.&mt('Exit now').'" onClick="javascript:location.href='."'$fullpath'".'" />
                    307:          </form>');
1.5       raeburn   308: }
                    309: 
                    310: # ---------------------------------------------------------------- Display Two
                    311: sub display_two {
1.36    ! raeburn   312:     my ($r,$zipupload,$areas,$areaname,$cmsmap,$fn,$numcrs,$fullpath) = @_;
1.5       raeburn   313:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['folder','source']);
1.11      albertel  314:     my $cms = $env{'form.source'};
1.36    ! raeburn   315:     my $tempdir = &Apache::imsprocessor::create_tempdir('CSTR',$env{'form.newdir'},'');
1.5       raeburn   316:     my $fname = &Apache::imsprocessor::uploadzip('CSTR',$tempdir,$zipupload);
                    317:     my $unzip_result = '';
                    318:     my $manifest_result = '';
                    319:     unless ($tempdir eq '') {
                    320:         $unzip_result = &Apache::imsprocessor::expand_zip($tempdir,$fname);
                    321:     }
                    322:     my %resources = ();
1.9       raeburn   323:     my %includedres = ();
                    324:     my %includeditems = ();
1.5       raeburn   325:     my %items = ();
                    326:     my %hrefs = ();
                    327:     my %resinfo = ();
                    328:     my %count = ();
1.23      raeburn   329: 
                    330:     my %lt = &Apache::lonlocal::texthash(
                    331:                   cont => 'Choose which content types you wish to import',
                    332:                   impo => 'Import',
                    333:                   type => 'Content type',
                    334:                   addo => 'Additional options',
                    335:                   chec => 'Check Import first',
                    336:                   bbus => 'Choose a course to receive bulletin boards and user enrollment',
                    337:                   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.',
                    338:                   chco => 'Choose course:',
                    339:                   nreq => 'Not required',
                    340:                   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).',
                    341:                   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.",
                    342:                   impa => 'Import package',
                    343:                   unpa => 'Unpacking of your IMS package failed because an IMS manifest file was not located in the package',
                    344:                   proc => 'Processing of your IMS package failed because the file you uploaded could not be unzipped',
                    345:                   exit => 'Exit now',
                    346:     );
1.5       raeburn   347: 
                    348:     my $counter = 0;
                    349:     my $iter = 0;
                    350:     my %count = (
                    351:                 announce => 0,
                    352:                 board => 0,
                    353:                 doc => 0,
                    354:                 extlink => 0,
                    355:                 msg => 0,
                    356:                 pool => 0,
                    357:                 quiz => 0,
                    358:                 staff => 0,
                    359:                 survey => 0,
                    360:                 users => 0,
                    361:                 );
                    362:     my $conditions;
                    363:     if ($unzip_result eq 'ok') {
1.19      raeburn   364:         $manifest_result = &Apache::imsprocessor::process_manifest($cms,
                    365:                             $tempdir,\%resources,\%items,\%hrefs,\%resinfo,
                    366:                             'choose',\%includedres,\%includeditems);
1.5       raeburn   367:         if ($manifest_result eq 'ok') {
                    368:             foreach my $res (sort keys %resources) {
1.19      raeburn   369:                 if ($cms eq 'bb5' || $cms eq 'bb6' || $cms eq 'webctce4' 
                    370:                     || $cms eq 'webctvista4') {
1.5       raeburn   371:                     foreach my $area (keys %{$$cmsmap{$cms}}) {
                    372:                         if ($resources{$res}{type} eq $$cmsmap{$cms}{$area}) {
                    373:                             $count{$area} ++;
                    374:                         }
                    375:                     }
1.32      raeburn   376:                 } elsif ($cms eq 'angel5') {
1.5       raeburn   377:                     foreach my $area (keys %{$$cmsmap{$cms}}) {
                    378:                         if ($area eq 'doc') {
                    379:                             if (grep/^$resources{$res}{type}$/,@{$$cmsmap{$cms}{doc}}) {
                    380:                                 $count{$area} ++;
                    381:                             }
                    382:                         } elsif ($resources{$res}{type} eq $$cmsmap{$cms}{$area}) {
                    383:                             $count{$area} ++;                                
                    384:                         }
                    385:                     }
                    386:                 }
                    387:             }
                    388:             if ($count{board} > 0) {
                    389:                 if ($count{users} > 0) {
                    390:                     $conditions = 'both';
                    391:                 } else {
                    392:                     $conditions = 'board';
                    393:                 }
                    394:             } elsif ($count{users} > 0) {
                    395:                 $conditions = 'users';
                    396:             } else {
                    397:                 $conditions = 'none';
                    398:             }
                    399: 
1.23      raeburn   400:             $r->print('<form name="pickoptions" method="post">'.
                    401:                       &Apache::lonhtmlcommon::topic_bar(3,$lt{'cont'}).
                    402:                       &Apache::loncommon::start_data_table().
                    403:                       &Apache::loncommon::start_data_table_header_row().
1.24      raeburn   404:                       '<th>'.$lt{'impo'}.'</th><th>'.$lt{'type'}.'</th><th>'.
1.23      raeburn   405:                       $lt{'addo'}.'</th>'.
                    406:                       &Apache::loncommon::end_data_table_header_row());
1.5       raeburn   407:             foreach my $area (@{$areas}) {
                    408:                 if ($count{$area} > 0) {
                    409:                     my $count_tag = 'flag_'.$counter;
1.23      raeburn   410:                     $r->print(&Apache::loncommon::start_data_table_row()."\n".
                    411:                               '<td><input name="'.$area.'" type="checkbox" ');
1.5       raeburn   412:                     if ($area eq 'board' || $area eq 'users') {
1.23      raeburn   413:                         $r->print('onClick="javascript:setOptions('."'$area','$counter'".');" ');
1.5       raeburn   414:                     }
1.23      raeburn   415:                     $r->print('/></td>'.
                    416:                               '<td>&nbsp;&nbsp;'.$$areaname{$area}.'&nbsp;&nbsp; - '.
                    417:                               &mt('[quant,_1,item]',$count{$area}).'</td>');
1.5       raeburn   418:                     if ($area eq 'board') {
1.23      raeburn   419:                         $r->print('<td>&nbsp;&nbsp;
                    420:                  <select name="db_handling">
                    421:                   <option value="-2">&lt;-- '.$lt{'chec'}.'</option>
                    422:                  </select>
                    423:                 </td>');
1.5       raeburn   424:                     } elsif ($area eq 'users') {
1.23      raeburn   425:                         $r->print('<td>&nbsp;&nbsp;
                    426:                  <select name="user_handling">
                    427:                   <option value="-2">&lt;-- '.$lt{'chec'}.'</option>
1.2       raeburn   428:                  </select>
1.23      raeburn   429:                 </td>');
1.5       raeburn   430:                     } else {
1.23      raeburn   431:                         $r->print('<td>&nbsp;&nbsp;'.&mt('None')."\n".
                    432:                                   '<input type="hidden" name="'.$count_tag.'" /></td>');
1.5       raeburn   433:                     }
                    434:                     $counter ++;
1.23      raeburn   435:                     $r->print(&Apache::loncommon::end_data_table_row());
1.5       raeburn   436:                 }
                    437:             }
1.23      raeburn   438:             $r->print(&Apache::loncommon::end_data_table());
1.5       raeburn   439:             if ($count{board} + $count{users} > 0) {
1.23      raeburn   440:                 $r->print(&Apache::lonhtmlcommon::topic_bar(4,$lt{'bbus'}));
1.5       raeburn   441:                 if ($$numcrs > 0) {
1.23      raeburn   442:                     $r->print($lt{'list'}.'<br /><br />'.$lt{'chco'}.'&nbsp;&nbsp;'."\n".
                    443:                               '<select name="targetcourse">
                    444:                                 <option value="-1">'.$lt{'nreq'}.'</option>
                    445:                                </select>');
1.5       raeburn   446:                 } else {
1.23      raeburn   447:                     $r->print($lt{'yodo'}.' '.$lt{'ifyo'});
                    448:                 }
                    449:             }
                    450:             $r->print('<br /><br />
                    451:           <input type="hidden" name="newdir" value="'.$env{'form.newdir'}.'" />
                    452:           <input type="hidden" name="conditions" value="'.$conditions.'" />
                    453:           <input type="hidden" name="source" value="'.$cms.'" />
                    454:           <input type="hidden" name="tempdir" value="'.$tempdir.'" />
1.36    ! raeburn   455:           <input type="hidden" name="filename" value="'.$fn.'" />
1.23      raeburn   456:           <input type="hidden" name="phase" value="four" />'."\n");
1.5       raeburn   457:             if ($count{board} == 0) {
1.23      raeburn   458:                 $r->print('<input type="hidden" name="board" value="" />'."\n");
1.5       raeburn   459:             }
                    460:             if ($count{users} == 0) {
1.23      raeburn   461:                 $r->print('<input type="hidden" name="users" value="" />'."\n");
1.5       raeburn   462:             }
1.23      raeburn   463:             $r->print('<input type="button" name="nextpage" value="'.$lt{'impa'}.'" onClick="javascript:nextPage('."'$counter.'".')" />&nbsp;&nbsp;&nbsp;
                    464:            <input type="button" name="exitpage" value="'.$lt{'exit'}.'" onClick="javascript:location.href='."'$fullpath'".'" /></form>');
1.5       raeburn   465:         } else {
1.23      raeburn   466:             $r->print($lt{'unpa'});
1.2       raeburn   467:         }
1.4       raeburn   468:     } else {
1.23      raeburn   469:         $r->print($lt{'proc'});
1.5       raeburn   470:     }
                    471: }
1.1       raeburn   472: 
1.5       raeburn   473: # ---------------------------------------------------------------- Display Three
                    474: sub display_three {
1.36    ! raeburn   475:     my ($r,$uname,$udom,$areas,$areaname,$cmsmap,$destdir,$dirpath) = @_;
1.5       raeburn   476:     my $crs = '';
                    477:     my $cdom = '';
                    478:     my $db_handling = '';
                    479:     my $timenow = time; 
                    480:     my $announce_handling = 'ok';
1.11      albertel  481:     my $cms = $env{'form.source'};
                    482:     if ( defined($env{'form.bb_crs'}) ) {
                    483:         ($cdom,$crs) = split/\//,$env{'form.bb_crs'};
1.4       raeburn   484:     } 
1.5       raeburn   485:     my $user_crs = '';
                    486:     my $user_cdom = '';
                    487:     my $user_handling = '';
1.11      albertel  488:     if ( defined($env{'form.user_crs'}) ) {
                    489:         ($user_cdom,$user_crs) = split/\//,$env{'form.user_crs'};
1.5       raeburn   490:     }
1.36    ! raeburn   491:     my $seqstem = "/res/$udom/$uname/$dirpath";
1.9       raeburn   492:     my %importareas = ();
                    493:     my %includedres = ();
                    494:     my %includeditems = ();
1.10      raeburn   495:     my %randompicks = ();
1.5       raeburn   496:     my @targets = ();
                    497:     my %resources = ();
                    498:     my %items = ();
                    499:     my %hrefs = ();
                    500:     my %urls = ();
                    501:     my %resinfo = ();
                    502:     my %total = (
                    503:                    page => 0,
                    504:                    prob => 0,
                    505:                    seq => 0,
                    506:                    board => 0,         
                    507:                    quiz => 0,
                    508:                    surv => 0,
1.23      raeburn   509:                    file => 0,
1.5       raeburn   510:     );
                    511: 
                    512:     my @pages = ();
                    513:     my @sequences = ();
                    514:     my @resrcfiles = ();
1.19      raeburn   515:     my @assessmentfiles = ();
1.5       raeburn   516: 
1.11      albertel  517:     my $tempdir = $env{'form.tempdir'};
1.5       raeburn   518: 
                    519:     foreach my $area (@{$areas}) {
1.11      albertel  520:         if (defined($env{"form.$area"}) ) {
1.32      raeburn   521:             if ($cms eq 'angel5' && $area eq 'doc') {
1.5       raeburn   522:                 foreach (@{$$cmsmap{$cms}{$area}}) {
1.9       raeburn   523:                     $importareas{$_} = 1;
1.1       raeburn   524:                 }
1.5       raeburn   525:             } else {
1.9       raeburn   526:                 $importareas{$$cmsmap{$cms}{$area}} = 1;
1.2       raeburn   527:             }
1.5       raeburn   528:             if ($area eq 'board') {
1.11      albertel  529:                 $db_handling = $env{'form.db_handling'};
1.5       raeburn   530:             } elsif ($area eq 'users') {
1.11      albertel  531:                 $user_handling = $env{'form.user_handling'};
1.4       raeburn   532:             }
1.1       raeburn   533:         }
                    534:     }
1.9       raeburn   535: 
1.23      raeburn   536:     my %lt = &Apache::lonlocal::texthash (
                    537:                  yims => 'Your IMS package has been processed successfully.',
                    538:                  plsv => 'Please view the imported items and use the LON-CAPA editing tools to make changes.',
                    539:                  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.",
                    540:                  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.',
                    541:                  disp => 'Display new directory',
                    542:                  proc => 'Processing of your IMS package failed, because the IMS content package did not contain an IMS manifest file.'
                    543:              );
1.19      raeburn   544:     my $manifest_result = &Apache::imsprocessor::process_manifest($cms,$tempdir,
                    545:                           \%resources,\%items,\%hrefs,\%resinfo,'prepare',
                    546:                           \%includedres);
1.9       raeburn   547:     if ($manifest_result eq 'ok') {
                    548:         foreach my $res (sort keys %resources) {
                    549:             if ($importareas{$resources{$res}{type}}) {
                    550:                 $includedres{$res} = 1;
1.19      raeburn   551:                 if ($resources{$res}{type} eq 'webct.manifest' || 
                    552:                      $resources{$res}{type} eq 'webct.assessment' ||
                    553:                      $resources{$res}{type} eq 'webct.question') {
                    554:                     push(@assessmentfiles,$res);
                    555:                 }   
1.9       raeburn   556:             }
                    557:         }
                    558:         foreach my $itm (sort keys %items) {
                    559:             &Apache::imsprocessor::get_imports(\%includeditems,\%items,\%resources,\%importareas,$itm);
                    560:         }
                    561:     }
                    562: 
                    563:     foreach my $itm (sort keys %includeditems) {
                    564:         &Apache::imsprocessor::get_parents(\%includeditems,\%items,$itm);
                    565:     }
                    566: 
1.19      raeburn   567:     $manifest_result = &Apache::imsprocessor::process_manifest($cms,$tempdir,
                    568:                        \%resources,\%items,\%hrefs,\%resinfo,'build',
                    569:                        \%includedres,\%includeditems);
1.5       raeburn   570:     if ($manifest_result eq 'ok') {
1.9       raeburn   571:         &Apache::imsprocessor::target_resources(\%resources,\%importareas,\@targets);
1.5       raeburn   572: 
                    573:         my @boards = ();
                    574:         my @announcements = ();
                    575:         my @quizzes = ();
                    576:         my @surveys = ();
1.9       raeburn   577:         my @pools = ();
1.5       raeburn   578:         my @groups = ();
                    579:         my %messages = ();
                    580:         my @timestamp = ();
                    581:         my %boardnum = ();
                    582:         my @topurls = ();
                    583:         my @topnames = ();
1.7       raeburn   584:         my @packages = ();
1.5       raeburn   585: 
1.10      raeburn   586:         &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   587: 
1.23      raeburn   588:         my $copy_result = &Apache::imsprocessor::copy_resources('CSTR',$cms,\%hrefs,$tempdir,\@targets,\%urls,$crs,$cdom,$destdir,$timenow,\@assessmentfiles,\%total);
1.5       raeburn   589:    
1.36    ! raeburn   590:         &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   591: 
1.9       raeburn   592:         $r->print("<h3>IMS import completed</h3>");
1.5       raeburn   593: 
1.32      raeburn   594:         if ($cms eq 'angel5') {
1.23      raeburn   595:             $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");
                    596:         } else {
                    597:             $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   598:         }
1.36    ! raeburn   599:         $r->print('<br /><br />'.$lt{'plsv'}.' '.$lt{'tseq'}.'<br /><br />'.$lt{'tfin'}.'<br /><br /><a href="/priv/'.$udom.'/'.$uname.'/'.$dirpath.'/">'.$lt{'disp'}.'</a>');
        !           600:         my $londocroot = $r->dir_config('lonDocRoot');
        !           601:         if ($destdir =~ m{^\Q$londocroot/priv/$udom/$uname/$dirpath\E}) {
1.9       raeburn   602:             system (" rm -r -f $destdir/temp");
                    603:         }
1.5       raeburn   604:     } elsif ($manifest_result eq 'nomanifest') {
1.23      raeburn   605:         $r->print($lt{'proc'});
1.4       raeburn   606:     }
1.5       raeburn   607: }
                    608: 
                    609: # ---------------------------------------------------------------- Get LON-CAPA Course Coordinator roles for this user
                    610: sub get_ccroles {
                    611:     my ($user,$dom,$crsentry,$crslist) = @_;
1.33      raeburn   612:     my %roles;
1.5       raeburn   613:     unless ($user eq '') {
1.33      raeburn   614:         my $ccrole = 'cc';
                    615:         %roles = &Apache::lonnet::get_my_roles($user,$dom,'userroles',undef,[$ccrole]);
1.4       raeburn   616:     }
1.5       raeburn   617:     my $iter = 0;
                    618:     my @codes = ();
                    619:     my %courses = ();
                    620:     my @crslist = ();
                    621:     my %descrip =();
1.33      raeburn   622:     foreach my $key (keys(%roles)) {
1.21      albertel  623:         if ($key =~ m{^/($LONCAPA::domain_re)/($LONCAPA::username_re)_cc$}) {
1.5       raeburn   624:             my $cdom = $1;
                    625:             my $crs = $2;
1.33      raeburn   626:             my $currcode = '';
                    627:             my %settings = &Apache::lonnet::get('environment',['internal.coursecode','description'],$cdom,$crs);
                    628:             if (defined($settings{'description'}) ) {
                    629:                 $descrip{$crs} = $settings{'description'};
                    630:             } else {
                    631:                 $descrip{$crs} = 'Unknown';
1.5       raeburn   632:             }
1.33      raeburn   633:             if (defined($settings{'internal.coursecode'}) ) {
                    634:                 $currcode = $settings{'internal.coursecode'};
                    635:                 if ($currcode eq '') {
1.5       raeburn   636:                     $currcode = "____".$iter;
                    637:                     $iter ++;
                    638:                 }
1.33      raeburn   639:             } else {
                    640:                 $currcode = "____".$iter;
                    641:                 $iter ++;
                    642:             }
                    643:             unless (grep/^$currcode$/,@codes) {
                    644:                 push @codes,$currcode;
                    645:                 @{$courses{$currcode}} = ();
1.1       raeburn   646:             }
1.33      raeburn   647:             push @{$courses{$currcode}}, $cdom.'/'.$crs;
1.5       raeburn   648:         }
                    649:     }
                    650:     foreach my $code (sort @codes) {
                    651:         foreach my $crsdom (@{$courses{$code}}) {
1.2       raeburn   652:             my ($cdom,$crs) = split/\//,$crsdom;
                    653:             my $showcode = '';
                    654:             unless ($code =~m/^____\d+$/) {  $showcode = $code; }
                    655:             $$crsentry{$crsdom} = $showcode.':'.$descrip{$crs};
1.5       raeburn   656:             push @{$crslist}, $crsdom;
1.2       raeburn   657:         }
                    658:     }
1.5       raeburn   659:     return;
1.2       raeburn   660: }
1.1       raeburn   661: 
                    662: # ---------------------------------------------------------------- Main Handler
                    663: sub handler {
                    664:     my $r=shift;
1.5       raeburn   665: 
1.36    ! raeburn   666:     my $fn=$env{'form.filename'};
1.5       raeburn   667: 
1.36    ! raeburn   668:     if ($env{'form.filename1'}) {
        !           669:         $fn=$env{'form.filename1'}.$env{'form.filename2'};
1.1       raeburn   670:     }
1.36    ! raeburn   671:     $fn=~s{\+}{}g;
        !           672: 
        !           673:     unless ($fn) {
1.11      albertel  674:         $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
1.1       raeburn   675:                        ' unspecified filename for upload', $r->filename);
                    676:         return HTTP_NOT_FOUND;
                    677:     }
1.36    ! raeburn   678: 
        !           679:     my ($uname,$udom) = &Apache::loncacc::constructaccess($fn);
        !           680:     if (($uname eq '') || ($udom eq '')) {
        !           681:         $r->log_reason($uname.' at '.$udom.
        !           682:                        ' trying to publish file '.$fn.' - not authorized',
        !           683:                        $r->filename);
        !           684:         return HTTP_NOT_ACCEPTABLE;
        !           685:     }
        !           686: 
        !           687:     my $londocroot = $r->dir_config('lonDocRoot');
        !           688:     my $zipupload = $londocroot.$fn;
        !           689:     my $fullpath = &File::Basename::dirname($fn);
        !           690:     unless ($fullpath =~ m{/$}) {
1.1       raeburn   691:         $fullpath .= '/';
                    692:     }
1.5       raeburn   693: 
1.36    ! raeburn   694: # get personal information for this user
        !           695:     my $user=$env{'user.name'};
        !           696:     my $dom=$env{'user.domain'};
        !           697: 
        !           698:     my $javascript = '';
        !           699:     my $page_name = '';
        !           700:     my $current_page = '';
        !           701:     my $qcount = '';
1.5       raeburn   702:     my @areas = ();
                    703:     my %cmsmap = ();
                    704:     my %areaname = ();
                    705:     my $numcrs = 0;
                    706:              
                    707:     &Apache::imsprocessor::ims_config(\@areas,\%cmsmap,\%areaname);
1.1       raeburn   708: # ----------------------------------------------------------- Start page output
                    709:     &Apache::loncommon::content_type($r,'text/html');
                    710:     $r->send_http_header;
1.5       raeburn   711: 
1.23      raeburn   712:     my $formname_one = 'info';
1.11      albertel  713:     if ($env{'form.phase'} eq 'two') {
1.36    ! raeburn   714:         $javascript = &jscript_one($fullpath,$formname_one);
1.11      albertel  715:     } elsif ($env{'form.phase'} eq 'three') {
1.36    ! raeburn   716:         $javascript = &jscript_two($user,$dom,\$numcrs);
        !           717:     }
        !           718:     if ($javascript ne '') {
        !           719:         $javascript = <<"END_JS";
        !           720: <script type="text/javascript">
        !           721: // <![CDATA[
        !           722: 
        !           723: $javascript
        !           724: 
        !           725: // ]]>
        !           726: </script>
        !           727: END_JS
1.1       raeburn   728:     }
1.14      albertel  729: 
                    730:     my $title = 'Upload IMS package to Construction Space';
1.20      albertel  731:     $r->print(&Apache::loncommon::start_page($title, $javascript));
1.14      albertel  732: 
1.11      albertel  733:     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
1.31      bisitz    734:         $r->print('<p><span class="LC_warning">'
                    735:                   .&mt('Co-Author [_1]',$uname.':'.$udom)
                    736:                   .'</span></p>'
1.29      bisitz    737:         );
1.36    ! raeburn   738:     }
1.11      albertel  739:     if ($env{'form.phase'} eq 'two') {
1.36    ! raeburn   740:         my $flag = &Apache::lonupload::phasetwo($r,$fn,'imsimport');
1.1       raeburn   741:         if ($flag eq 'ok') {
1.36    ! raeburn   742:             &display_one($r,$fn,$fullpath,$formname_one);
1.5       raeburn   743:         }
1.11      albertel  744:     } elsif ( ($env{'form.phase'} eq 'three') || ($env{'form.phase'} eq 'four') ) {
1.36    ! raeburn   745:         my $destdir = $env{'form.newdir'};
        !           746:         my $dirpath = $destdir;
        !           747:         $dirpath =~ s{^\Q$londocroot/priv/$udom/$uname/\E}{};
        !           748: 
1.11      albertel  749:         if ($env{'form.phase'} eq 'three') {
1.36    ! raeburn   750:             &display_two($r,$zipupload,\@areas,\%areaname,\%cmsmap,$fn,\$numcrs,$fullpath);
1.11      albertel  751:         } elsif ($env{'form.phase'} eq 'four') {
1.36    ! raeburn   752:             &display_three($r,$uname,$udom,\@areas,\%areaname,\%cmsmap,$destdir,$dirpath);
1.1       raeburn   753:         }
                    754:     } else {
1.36    ! raeburn   755:         &Apache::lonupload::phaseone($r,$fn,'imsimport');
1.1       raeburn   756:     }
1.14      albertel  757:     $r->print(&Apache::loncommon::end_page());
1.1       raeburn   758:     return OK;
                    759: }
                    760: 1;
                    761: __END__

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