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