Annotation of loncom/interface/lonclonecourse.pm, revision 1.12
1.1 albertel 1: # The LearningOnline Network
2: # routines for clone a course
3: #
1.12 ! raeburn 4: # $Id: lonclonecourse.pm,v 1.11 2015/06/23 17:49:06 musolffc Exp $
1.1 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: ###
29:
30: package Apache::lonclonecourse;
31: use LONCAPA;
32: use Apache::lonnet;
1.12 ! raeburn 33: use DateTime();
! 34: use DateTime::TimeZone;
1.1 albertel 35:
36: # ================================================ Get course directory listing
37:
38: my @output=();
39:
40: sub crsdirlist {
41: my ($courseid,$which)=@_;
42: @output=();
43: return &innercrsdirlist($courseid,$which);
44: }
45:
46: sub innercrsdirlist {
47: my ($courseid,$which,$path)=@_;
48: my $dirptr=16384;
49: unless ($which) { $which=''; } else { $which.='/'; }
50: unless ($path) { $path=''; } else { $path.='/'; }
51: my %crsdata=&Apache::lonnet::coursedescription($courseid);
1.7 raeburn 52: my $getpropath = 1;
1.8 raeburn 53: my ($dirlistref,$listerror) =
54: &Apache::lonnet::dirlist($which,$crsdata{'domain'},
55: $crsdata{'num'},$getpropath);
56: if (ref($dirlistref) eq 'ARRAY') {
57: foreach (@{$dirlistref}) {
58: unless ($_=~/^\./) {
59: my @unpackline = split (/\&/,$_);
60: if ($unpackline[3]&$dirptr) {
1.1 albertel 61: # is a directory, recurse
1.8 raeburn 62: &innercrsdirlist($courseid,$which.$unpackline[0],
63: $path.$unpackline[0]);
64: } else {
1.1 albertel 65: # is a file, put into output
1.8 raeburn 66: push (@output,$path.$unpackline[0]);
67: }
1.1 albertel 68: }
1.8 raeburn 69: }
1.1 albertel 70: }
71: return @output;
72: }
73:
74: # ============================================================= Read a userfile
75:
76: sub readfile {
77: my ($courseid,$which)=@_;
78: my %crsdata=&Apache::lonnet::coursedescription($courseid);
79: my $file = &Apache::lonnet::getfile('/uploaded/'.$crsdata{'domain'}.'/'.
80: $crsdata{'num'}.'/'.$which);
81: return $file;
82: }
83:
84: # ============================================================ Write a userfile
85:
86: sub writefile {
87: (my $courseid, my $which,$env{'form.output'})=@_;
88: my %crsdata=&Apache::lonnet::coursedescription($courseid);
89: my $data = &Apache::lonnet::finishuserfileupload(
90: $crsdata{'num'},$crsdata{'domain'},
91: 'output',$which);
92: return $data;
93: }
94:
95: # ===================================================================== Rewrite
96:
97: sub rewritefile {
98: my ($contents,%rewritehash)=@_;
1.2 albertel 99: foreach my $pattern (keys(%rewritehash)) {
100: my $new=$rewritehash{$pattern};
101: $contents=~s/\Q$pattern\E/$new/gs;
1.1 albertel 102: }
103: return $contents;
104: }
105:
106: # ============================================================= Copy a userfile
107:
108: sub copyfile {
109: my ($origcrsid,$newcrsid,$which)=@_;
110: unless ($which=~/\.sequence$/) {
111: return &writefile($newcrsid,$which,
112: &readfile($origcrsid,$which));
113: } else {
114: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
115: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
116: return &writefile($newcrsid,$which,
117: &rewritefile(
118: &readfile($origcrsid,$which),
119: (
120: '/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'
121: => '/uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/',
122: '/public/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'
1.4 raeburn 123: => '/public/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/',
124: '/adm/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'
125: => '/adm/'.$newcrsdata{'domain'}.'/'.$newcrsdata{'num'}.'/',
1.1 albertel 126: )));
127: }
128: }
129:
130: # =============================================================== Copy a dbfile
131:
132: sub copydb {
133: my ($origcrsid,$newcrsid,$which)=@_;
134: $which=~s/\.db$//;
135: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
136: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
137: my %data=&Apache::lonnet::dump
138: ($which,$origcrsdata{'domain'},$origcrsdata{'num'});
139: foreach my $key (keys(%data)) {
140: if ($key=~/^internal./) { delete($data{$key}); }
141: }
142: return &Apache::lonnet::put
143: ($which,\%data,$newcrsdata{'domain'},$newcrsdata{'num'});
144: }
145:
146: # ========================================================== Copy resourcesdata
147:
148: sub copyresourcedb {
1.6 www 149: my ($origcrsid,$newcrsid,$date_mode,$date_shift)=@_;
150: my $delta=$date_shift*60*60*24;
1.1 albertel 151: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
152: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
1.12 ! raeburn 153: my $origtz;
! 154: if (($date_mode) && ($date_mode ne 'preserve') && ($date_shift) &&
! 155: (int($date_shift) == $date_shift)) {
! 156: $origtz = $origcrsdata{'timezone'};
! 157: if ($origtz eq '') {
! 158: my %domdefaults = &Apache::lonnet::get_domain_defaults($origcrsdata{'domain'});
! 159: if ($domdefaults{'timezone_def'} ne '') {
! 160: $origtz = $domdefaults{'timezone_def'};
! 161: }
! 162: }
! 163: if ($origtz eq '') {
! 164: $origtz = 'local';
! 165: } elsif (!DateTime::TimeZone->is_valid_name($origtz)) {
! 166: $origtz = 'local';
! 167: }
! 168: }
1.1 albertel 169: my %data=&Apache::lonnet::dump
170: ('resourcedata',$origcrsdata{'domain'},$origcrsdata{'num'});
171: $origcrsid=~s/^\///;
172: $origcrsid=~s/\//\_/;
173: $newcrsid=~s/^\///;
174: $newcrsid=~s/\//\_/;
175: my %newdata=();
176: undef %newdata;
177: my $startdate=$data{$origcrsid.'.0.opendate'};
178: if (!$startdate) {
179: # now global start date for assements try the enrollment start
180: my %start=&Apache::lonnet::get('environment',
181: ['default_enrollment_start_date'],
182: $origcrsdata{'domain'},$origcrsdata{'num'});
183:
184: $startdate = $start{'default_enrollment_start_date'};
185: }
186: # ugly retro fix for broken version of types
1.10 raeburn 187: foreach my $key (keys(%data)) {
1.6 www 188: if ($key=~/\wtype$/) {
189: my $newkey=$key;
1.1 albertel 190: $newkey=~s/type$/\.type/;
1.6 www 191: $data{$newkey}=$data{$key};
192: delete $data{$key};
1.1 albertel 193: }
194: }
195: # adjust symbs
196: my $pattern='uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/';
197: my $new= 'uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/';
1.10 raeburn 198: foreach my $key (keys(%data)) {
1.6 www 199: if ($key=~/\Q$pattern\E/) {
200: my $newkey=$key;
1.2 albertel 201: $newkey=~s/\Q$pattern\E/$new/;
1.6 www 202: $data{$newkey}=$data{$key};
203: delete $data{$key};
204: }
205: }
206: # transfer hash
1.10 raeburn 207: foreach my $key (keys(%data)) {
1.6 www 208: my $thiskey=$key;
209: $thiskey=~s/^$origcrsid/$newcrsid/;
210: $newdata{$thiskey}=$data{$key};
211: # date_mode empty or "preserve": transfer dates one-to-one
212: # date_mode "shift": shift dates by date_shift days
213: # date_mode other: do not transfer dates
214: if (($date_mode) && ($date_mode ne 'preserve')) {
215: if ($data{$key.'.type'}=~/^date_(start|end)$/) {
1.12 ! raeburn 216: if ($date_mode eq 'shift') {
! 217: if (($date_shift) && ($date_shift == int($date_shift))) {
! 218: my $dt = DateTime->from_epoch(epoch => $newdata{$thiskey})
! 219: ->set_time_zone($origtz);
! 220: if (($origtz eq 'local') && (!$ENV{TZ})) {
! 221: $ENV{TZ} = $dt->time_zone()->name();
! 222: }
! 223: $dt->add(days => int($date_shift));
! 224: $newdata{$thiskey} = $dt->epoch();
! 225: } else {
! 226: $newdata{$thiskey} = $newdata{$thiskey}+$delta;
! 227: }
! 228: } else {
! 229: delete($newdata{$thiskey});
! 230: delete($newdata{$thiskey.'.type'});
! 231: }
1.6 www 232: }
1.12 ! raeburn 233: }
1.1 albertel 234: }
235: return &Apache::lonnet::put
236: ('resourcedata',\%newdata,$newcrsdata{'domain'},$newcrsdata{'num'});
237: }
238:
239: # ========================================================== Copy all userfiles
240:
241: sub copyuserfiles {
242: my ($origcrsid,$newcrsid)=@_;
243: foreach (&crsdirlist($origcrsid,'userfiles')) {
244: if ($_ !~m|^scantron_|) {
245: ©file($origcrsid,$newcrsid,$_);
246: }
247: }
248: }
249: # ========================================================== Copy all userfiles
250:
251: sub copydbfiles {
252: my ($origcrsid,$newcrsid)=@_;
253:
254: my ($origcrs_discussion) = ($origcrsid=~m|^/(.*)|);
255: $origcrs_discussion=~s|/|_|g;
256: foreach (&crsdirlist($origcrsid)) {
257: if ($_=~/\.db$/) {
1.11 musolffc 258: unless ($_=~/^(nohist\_|disclikes|discussiontimes|classlist|versionupdate
259: |resourcedata|\Q$origcrs_discussion\E|slots|slot_reservations
260: |gradingqueue|reviewqueue|CODEs|groupmembership|comm_block)/) {
261: ©db($origcrsid,$newcrsid,$_);
262: }
1.1 albertel 263: }
264: }
265: }
266:
267: # ======================================================= Copy all course files
268:
269: sub copycoursefiles {
1.6 www 270: my ($origcrsid,$newcrsid,$date_mode,$date_shift)=@_;
1.1 albertel 271: ©userfiles($origcrsid,$newcrsid);
272: ©dbfiles($origcrsid,$newcrsid);
1.6 www 273: ©resourcedb($origcrsid,$newcrsid,$date_mode,$date_shift);
1.1 albertel 274: }
275:
276: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>