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

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

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