--- loncom/interface/lonclonecourse.pm 2007/08/02 01:34:07 1.3 +++ loncom/interface/lonclonecourse.pm 2020/07/24 18:06:24 1.13.2.1 @@ -1,7 +1,7 @@ # The LearningOnline Network # routines for clone a course # -# $Id: lonclonecourse.pm,v 1.3 2007/08/02 01:34:07 albertel Exp $ +# $Id: lonclonecourse.pm,v 1.13.2.1 2020/07/24 18:06:24 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -30,6 +30,8 @@ package Apache::lonclonecourse; use LONCAPA; use Apache::lonnet; +use DateTime(); +use DateTime::TimeZone; # ================================================ Get course directory listing @@ -47,21 +49,24 @@ sub innercrsdirlist { unless ($which) { $which=''; } else { $which.='/'; } unless ($path) { $path=''; } else { $path.='/'; } my %crsdata=&Apache::lonnet::coursedescription($courseid); - my @listing=&Apache::lonnet::dirlist - ($which,$crsdata{'domain'},$crsdata{'num'}, - &propath($crsdata{'domain'},$crsdata{'num'})); - foreach (@listing) { - unless ($_=~/^\./) { - my @unpackline = split (/\&/,$_); - if ($unpackline[3]&$dirptr) { + my $getpropath = 1; + my ($dirlistref,$listerror) = + &Apache::lonnet::dirlist($which,$crsdata{'domain'}, + $crsdata{'num'},$getpropath); + if (ref($dirlistref) eq 'ARRAY') { + foreach (@{$dirlistref}) { + unless ($_=~/^\./) { + my @unpackline = split (/\&/,$_); + if ($unpackline[3]&$dirptr) { # is a directory, recurse - &innercrsdirlist($courseid,$which.$unpackline[0], - $path.$unpackline[0]); - } else { + &innercrsdirlist($courseid,$which.$unpackline[0], + $path.$unpackline[0]); + } else { # is a file, put into output - push (@output,$path.$unpackline[0]); + push (@output,$path.$unpackline[0]); + } } - } + } } return @output; } @@ -102,7 +107,7 @@ sub rewritefile { sub copyfile { my ($origcrsid,$newcrsid,$which)=@_; - unless ($which=~/\.sequence$/) { + unless ($which=~/\.(page|sequence)$/) { return &writefile($newcrsid,$which, &readfile($origcrsid,$which)); } else { @@ -115,7 +120,9 @@ sub copyfile { '/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/' => '/uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/', '/public/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/' - => '/public/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/' + => '/public/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/', + '/adm/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/' + => '/adm/'.$newcrsdata{'domain'}.'/'.$newcrsdata{'num'}.'/', ))); } } @@ -139,9 +146,26 @@ sub copydb { # ========================================================== Copy resourcesdata sub copyresourcedb { - my ($origcrsid,$newcrsid)=@_; + my ($origcrsid,$newcrsid,$date_mode,$date_shift)=@_; + my $delta=$date_shift*60*60*24; my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid); my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid); + my $origtz; + if (($date_mode) && ($date_mode ne 'preserve') && ($date_shift) && + (int($date_shift) == $date_shift)) { + $origtz = $origcrsdata{'timezone'}; + if ($origtz eq '') { + my %domdefaults = &Apache::lonnet::get_domain_defaults($origcrsdata{'domain'}); + if ($domdefaults{'timezone_def'} ne '') { + $origtz = $domdefaults{'timezone_def'}; + } + } + if ($origtz eq '') { + $origtz = 'local'; + } elsif (!DateTime::TimeZone->is_valid_name($origtz)) { + $origtz = 'local'; + } + } my %data=&Apache::lonnet::dump ('resourcedata',$origcrsdata{'domain'},$origcrsdata{'num'}); $origcrsid=~s/^\///; @@ -159,47 +183,60 @@ sub copyresourcedb { $startdate = $start{'default_enrollment_start_date'}; } - my $today=time; - my $delta=0; - if ($startdate) { - my $oneday=60*60*24; - $delta=$today-$startdate; - $delta=int($delta/$oneday)*$oneday; - } # ugly retro fix for broken version of types - foreach (keys %data) { - if ($_=~/\wtype$/) { - my $newkey=$_; + foreach my $key (keys(%data)) { + if ($key=~/\wtype$/) { + my $newkey=$key; $newkey=~s/type$/\.type/; - $data{$newkey}=$data{$_}; - delete $data{$_}; + $data{$newkey}=$data{$key}; + delete $data{$key}; } } # adjust symbs my $pattern='uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'; my $new= 'uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/'; - foreach (keys %data) { - if ($_=~/\Q$pattern\E/) { - my $newkey=$_; + foreach my $key (keys(%data)) { + if ($key=~/\Q$pattern\E/) { + my $newkey=$key; $newkey=~s/\Q$pattern\E/$new/; - $data{$newkey}=$data{$_}; - delete $data{$_}; + $data{$newkey}=$data{$key}; + delete $data{$key}; } } -# adjust dates - foreach (keys %data) { - my $thiskey=$_; +# transfer hash + foreach my $key (keys(%data)) { + my $thiskey=$key; $thiskey=~s/^$origcrsid/$newcrsid/; - $newdata{$thiskey}=$data{$_}; - if ($data{$_.'.type'}=~/^date_(start|end)$/) { - if ($delta > 0) { - $newdata{$thiskey}=$newdata{$thiskey}+$delta; - } else { - # no delta, it's unlikely we want the old dates and times - delete($newdata{$thiskey}); - delete($newdata{$thiskey.'.type'}); - } - } + $newdata{$thiskey}=$data{$key}; +# date_mode empty or "preserve": transfer dates one-to-one +# date_mode "shift": shift dates by date_shift days +# date_mode other: do not transfer dates + if (($date_mode) && ($date_mode ne 'preserve')) { + if ($data{$key.'.type'}=~/^date_(start|end)$/) { + if ($date_mode eq 'shift') { + if (($date_shift) && ($date_shift == int($date_shift))) { + my $dt = DateTime->from_epoch(epoch => $newdata{$thiskey}) + ->set_time_zone($origtz); + if (($origtz eq 'local') && (!$ENV{TZ})) { + $ENV{TZ} = $dt->time_zone()->name(); + } + eval { + $dt->add(days => int($date_shift)); + }; + if ($@) { + $newdata{$thiskey} = $newdata{$thiskey}+$delta+(60*60); + } else { + $newdata{$thiskey} = $dt->epoch(); + } + } else { + $newdata{$thiskey} = $newdata{$thiskey}+$delta; + } + } else { + delete($newdata{$thiskey}); + delete($newdata{$thiskey.'.type'}); + } + } + } } return &Apache::lonnet::put ('resourcedata',\%newdata,$newcrsdata{'domain'},$newcrsdata{'num'}); @@ -224,10 +261,11 @@ sub copydbfiles { $origcrs_discussion=~s|/|_|g; foreach (&crsdirlist($origcrsid)) { if ($_=~/\.db$/) { - unless - ($_=~/^(nohist\_|discussiontimes|classlist|versionupdate|resourcedata|\Q$origcrs_discussion\E|slots|slot_reservations|gradingqueue|reviewqueue|CODEs|groupmembership)/) { - ©db($origcrsid,$newcrsid,$_); - } + unless ($_=~/^(nohist\_|disclikes|discussiontimes|classlist|versionupdate + |resourcedata|\Q$origcrs_discussion\E|slots|slot_reservations + |gradingqueue|reviewqueue|CODEs|groupmembership|comm_block)/) { + ©db($origcrsid,$newcrsid,$_); + } } } } @@ -235,10 +273,10 @@ sub copydbfiles { # ======================================================= Copy all course files sub copycoursefiles { - my ($origcrsid,$newcrsid)=@_; + my ($origcrsid,$newcrsid,$date_mode,$date_shift)=@_; ©userfiles($origcrsid,$newcrsid); ©dbfiles($origcrsid,$newcrsid); - ©resourcedb($origcrsid,$newcrsid); + ©resourcedb($origcrsid,$newcrsid,$date_mode,$date_shift); } 1;