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

1.25      www         1: # The LearningOnline Network with CAPA
                      2: # 
1.38    ! raeburn     3: # $Id: imsimport.pm,v 1.37 2012/10/04 14:00:22 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.23      raeburn   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.23      raeburn   289:     $r->print('<form name="'.$formname.'" method="post">'.
                    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".
                    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 />
                    302:           <input type="hidden" name="filename" value="'.$fn.'" />
1.15      albertel  303:           <input type="hidden" name="phase" value="three" />
1.23      raeburn   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'".'" />
                    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.23      raeburn   399:             $r->print('<form name="pickoptions" method="post">'.
                    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.23      raeburn   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.23      raeburn   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.",
                    539:                  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.',
                    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.9       raeburn   546:     if ($manifest_result eq 'ok') {
                    547:         foreach my $res (sort keys %resources) {
                    548:             if ($importareas{$resources{$res}{type}}) {
                    549:                 $includedres{$res} = 1;
1.19      raeburn   550:                 if ($resources{$res}{type} eq 'webct.manifest' || 
                    551:                      $resources{$res}{type} eq 'webct.assessment' ||
                    552:                      $resources{$res}{type} eq 'webct.question') {
                    553:                     push(@assessmentfiles,$res);
                    554:                 }   
1.9       raeburn   555:             }
                    556:         }
                    557:         foreach my $itm (sort keys %items) {
                    558:             &Apache::imsprocessor::get_imports(\%includeditems,\%items,\%resources,\%importareas,$itm);
                    559:         }
                    560:     }
                    561: 
                    562:     foreach my $itm (sort keys %includeditems) {
                    563:         &Apache::imsprocessor::get_parents(\%includeditems,\%items,$itm);
                    564:     }
                    565: 
1.19      raeburn   566:     $manifest_result = &Apache::imsprocessor::process_manifest($cms,$tempdir,
                    567:                        \%resources,\%items,\%hrefs,\%resinfo,'build',
                    568:                        \%includedres,\%includeditems);
1.5       raeburn   569:     if ($manifest_result eq 'ok') {
1.9       raeburn   570:         &Apache::imsprocessor::target_resources(\%resources,\%importareas,\@targets);
1.5       raeburn   571: 
                    572:         my @boards = ();
                    573:         my @announcements = ();
                    574:         my @quizzes = ();
                    575:         my @surveys = ();
1.9       raeburn   576:         my @pools = ();
1.5       raeburn   577:         my @groups = ();
                    578:         my %messages = ();
                    579:         my @timestamp = ();
                    580:         my %boardnum = ();
                    581:         my @topurls = ();
                    582:         my @topnames = ();
1.7       raeburn   583:         my @packages = ();
1.5       raeburn   584: 
1.10      raeburn   585:         &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   586: 
1.23      raeburn   587:         my $copy_result = &Apache::imsprocessor::copy_resources('CSTR',$cms,\%hrefs,$tempdir,\@targets,\%urls,$crs,$cdom,$destdir,$timenow,\@assessmentfiles,\%total);
1.5       raeburn   588:    
1.36      raeburn   589:         &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   590: 
1.9       raeburn   591:         $r->print("<h3>IMS import completed</h3>");
1.5       raeburn   592: 
1.32      raeburn   593:         if ($cms eq 'angel5') {
1.23      raeburn   594:             $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");
                    595:         } else {
                    596:             $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   597:         }
1.36      raeburn   598:         $r->print('<br /><br />'.$lt{'plsv'}.' '.$lt{'tseq'}.'<br /><br />'.$lt{'tfin'}.'<br /><br /><a href="/priv/'.$udom.'/'.$uname.'/'.$dirpath.'/">'.$lt{'disp'}.'</a>');
                    599:         my $londocroot = $r->dir_config('lonDocRoot');
                    600:         if ($destdir =~ m{^\Q$londocroot/priv/$udom/$uname/$dirpath\E}) {
1.9       raeburn   601:             system (" rm -r -f $destdir/temp");
                    602:         }
1.5       raeburn   603:     } elsif ($manifest_result eq 'nomanifest') {
1.23      raeburn   604:         $r->print($lt{'proc'});
1.4       raeburn   605:     }
1.5       raeburn   606: }
                    607: 
                    608: # ---------------------------------------------------------------- Get LON-CAPA Course Coordinator roles for this user
                    609: sub get_ccroles {
                    610:     my ($user,$dom,$crsentry,$crslist) = @_;
1.33      raeburn   611:     my %roles;
1.5       raeburn   612:     unless ($user eq '') {
1.33      raeburn   613:         my $ccrole = 'cc';
                    614:         %roles = &Apache::lonnet::get_my_roles($user,$dom,'userroles',undef,[$ccrole]);
1.4       raeburn   615:     }
1.5       raeburn   616:     my $iter = 0;
                    617:     my @codes = ();
                    618:     my %courses = ();
                    619:     my @crslist = ();
                    620:     my %descrip =();
1.33      raeburn   621:     foreach my $key (keys(%roles)) {
1.21      albertel  622:         if ($key =~ m{^/($LONCAPA::domain_re)/($LONCAPA::username_re)_cc$}) {
1.5       raeburn   623:             my $cdom = $1;
                    624:             my $crs = $2;
1.33      raeburn   625:             my $currcode = '';
                    626:             my %settings = &Apache::lonnet::get('environment',['internal.coursecode','description'],$cdom,$crs);
                    627:             if (defined($settings{'description'}) ) {
                    628:                 $descrip{$crs} = $settings{'description'};
                    629:             } else {
                    630:                 $descrip{$crs} = 'Unknown';
1.5       raeburn   631:             }
1.33      raeburn   632:             if (defined($settings{'internal.coursecode'}) ) {
                    633:                 $currcode = $settings{'internal.coursecode'};
                    634:                 if ($currcode eq '') {
1.5       raeburn   635:                     $currcode = "____".$iter;
                    636:                     $iter ++;
                    637:                 }
1.33      raeburn   638:             } else {
                    639:                 $currcode = "____".$iter;
                    640:                 $iter ++;
                    641:             }
                    642:             unless (grep/^$currcode$/,@codes) {
                    643:                 push @codes,$currcode;
                    644:                 @{$courses{$currcode}} = ();
1.1       raeburn   645:             }
1.33      raeburn   646:             push @{$courses{$currcode}}, $cdom.'/'.$crs;
1.5       raeburn   647:         }
                    648:     }
                    649:     foreach my $code (sort @codes) {
                    650:         foreach my $crsdom (@{$courses{$code}}) {
1.2       raeburn   651:             my ($cdom,$crs) = split/\//,$crsdom;
                    652:             my $showcode = '';
                    653:             unless ($code =~m/^____\d+$/) {  $showcode = $code; }
                    654:             $$crsentry{$crsdom} = $showcode.':'.$descrip{$crs};
1.5       raeburn   655:             push @{$crslist}, $crsdom;
1.2       raeburn   656:         }
                    657:     }
1.5       raeburn   658:     return;
1.2       raeburn   659: }
1.1       raeburn   660: 
                    661: # ---------------------------------------------------------------- Main Handler
                    662: sub handler {
                    663:     my $r=shift;
1.5       raeburn   664: 
1.36      raeburn   665:     my $fn=$env{'form.filename'};
1.5       raeburn   666: 
1.36      raeburn   667:     if ($env{'form.filename1'}) {
                    668:         $fn=$env{'form.filename1'}.$env{'form.filename2'};
1.1       raeburn   669:     }
1.36      raeburn   670:     $fn=~s{\+}{}g;
                    671: 
                    672:     unless ($fn) {
1.11      albertel  673:         $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
1.1       raeburn   674:                        ' unspecified filename for upload', $r->filename);
                    675:         return HTTP_NOT_FOUND;
                    676:     }
1.36      raeburn   677: 
1.38    ! raeburn   678:     my ($uname,$udom) = &Apache::lonnet::constructaccess($fn);
1.36      raeburn   679:     if (($uname eq '') || ($udom eq '')) {
                    680:         $r->log_reason($uname.' at '.$udom.
                    681:                        ' trying to publish file '.$fn.' - not authorized',
                    682:                        $r->filename);
                    683:         return HTTP_NOT_ACCEPTABLE;
                    684:     }
                    685: 
                    686:     my $londocroot = $r->dir_config('lonDocRoot');
                    687:     my $zipupload = $londocroot.$fn;
                    688:     my $fullpath = &File::Basename::dirname($fn);
                    689:     unless ($fullpath =~ m{/$}) {
1.1       raeburn   690:         $fullpath .= '/';
                    691:     }
1.5       raeburn   692: 
1.36      raeburn   693: # get personal information for this user
                    694:     my $user=$env{'user.name'};
                    695:     my $dom=$env{'user.domain'};
                    696: 
                    697:     my $javascript = '';
                    698:     my $page_name = '';
                    699:     my $current_page = '';
                    700:     my $qcount = '';
1.5       raeburn   701:     my @areas = ();
                    702:     my %cmsmap = ();
                    703:     my %areaname = ();
                    704:     my $numcrs = 0;
                    705:              
                    706:     &Apache::imsprocessor::ims_config(\@areas,\%cmsmap,\%areaname);
1.1       raeburn   707: # ----------------------------------------------------------- Start page output
                    708:     &Apache::loncommon::content_type($r,'text/html');
                    709:     $r->send_http_header;
1.5       raeburn   710: 
1.23      raeburn   711:     my $formname_one = 'info';
1.11      albertel  712:     if ($env{'form.phase'} eq 'two') {
1.36      raeburn   713:         $javascript = &jscript_one($fullpath,$formname_one);
1.11      albertel  714:     } elsif ($env{'form.phase'} eq 'three') {
1.36      raeburn   715:         $javascript = &jscript_two($user,$dom,\$numcrs);
                    716:     }
                    717:     if ($javascript ne '') {
                    718:         $javascript = <<"END_JS";
                    719: <script type="text/javascript">
                    720: // <![CDATA[
                    721: 
                    722: $javascript
                    723: 
                    724: // ]]>
                    725: </script>
                    726: END_JS
1.1       raeburn   727:     }
1.14      albertel  728: 
                    729:     my $title = 'Upload IMS package to Construction Space';
1.20      albertel  730:     $r->print(&Apache::loncommon::start_page($title, $javascript));
1.14      albertel  731: 
1.11      albertel  732:     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
1.37      bisitz    733:         $r->print('<p><span class="LC_info">'
1.31      bisitz    734:                   .&mt('Co-Author [_1]',$uname.':'.$udom)
                    735:                   .'</span></p>'
1.29      bisitz    736:         );
1.36      raeburn   737:     }
1.11      albertel  738:     if ($env{'form.phase'} eq 'two') {
1.36      raeburn   739:         my $flag = &Apache::lonupload::phasetwo($r,$fn,'imsimport');
1.1       raeburn   740:         if ($flag eq 'ok') {
1.36      raeburn   741:             &display_one($r,$fn,$fullpath,$formname_one);
1.5       raeburn   742:         }
1.11      albertel  743:     } elsif ( ($env{'form.phase'} eq 'three') || ($env{'form.phase'} eq 'four') ) {
1.36      raeburn   744:         my $destdir = $env{'form.newdir'};
                    745:         my $dirpath = $destdir;
                    746:         $dirpath =~ s{^\Q$londocroot/priv/$udom/$uname/\E}{};
                    747: 
1.11      albertel  748:         if ($env{'form.phase'} eq 'three') {
1.36      raeburn   749:             &display_two($r,$zipupload,\@areas,\%areaname,\%cmsmap,$fn,\$numcrs,$fullpath);
1.11      albertel  750:         } elsif ($env{'form.phase'} eq 'four') {
1.36      raeburn   751:             &display_three($r,$uname,$udom,\@areas,\%areaname,\%cmsmap,$destdir,$dirpath);
1.1       raeburn   752:         }
                    753:     } else {
1.36      raeburn   754:         &Apache::lonupload::phaseone($r,$fn,'imsimport');
1.1       raeburn   755:     }
1.14      albertel  756:     $r->print(&Apache::loncommon::end_page());
1.1       raeburn   757:     return OK;
                    758: }
                    759: 1;
                    760: __END__

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