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