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