version 1.87, 2002/08/07 19:50:22
|
version 1.91, 2002/08/09 18:03:05
|
Line 61
|
Line 61
|
## ## |
## ## |
############################################################################### |
############################################################################### |
|
|
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
=pod |
|
|
|
=head1 Name |
|
|
|
lonpublisher - LON-CAPA publishing handler |
|
|
|
=head1 Synopsis |
|
|
|
lonpublisher takes the proper steps to add resources to the LON-CAPA |
|
digital library. This includes updating the metadata table in the |
|
LON-CAPA database. |
|
|
|
=head1 Description |
|
|
|
lonpublisher is many things to many people. |
|
To all people it is woefully documented. |
|
This documentation conforms to this standard. |
|
|
|
This module publishes a file. This involves gathering metadata, |
|
versioning the file, copying file from construction space to |
|
publication space, and copying metadata from construction space |
|
to publication space. |
|
|
|
=head2 Internal Functions |
|
|
|
=over 4 |
|
|
|
=cut |
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
|
package Apache::lonpublisher; |
package Apache::lonpublisher; |
|
|
# ------------------------------------------------- modules used by this module |
# ------------------------------------------------- modules used by this module |
Line 75 use Apache::loncacc;
|
Line 112 use Apache::loncacc;
|
use DBI; |
use DBI; |
use Apache::lonnet(); |
use Apache::lonnet(); |
use Apache::loncommon(); |
use Apache::loncommon(); |
|
use Apache::lonmysql; |
|
|
my %addid; |
my %addid; |
my %nokey; |
my %nokey; |
Line 87 my $docroot;
|
Line 125 my $docroot;
|
my $cuname; |
my $cuname; |
my $cudom; |
my $cudom; |
|
|
# ----------------------------------------------- Evaluate string with metadata |
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item metaeval |
|
|
|
Evaluate string with metadata |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub metaeval { |
sub metaeval { |
my $metastring=shift; |
my $metastring=shift; |
|
|
Line 130 sub metaeval {
|
Line 180 sub metaeval {
|
} |
} |
} |
} |
|
|
# -------------------------------------------------------- Read a metadata file |
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item metaread |
|
|
|
Read a metadata file |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub metaread { |
sub metaread { |
my ($logfile,$fn)=@_; |
my ($logfile,$fn)=@_; |
unless (-e $fn) { |
unless (-e $fn) { |
Line 147 sub metaread {
|
Line 209 sub metaread {
|
return '<br><b>Processed file:</b> <tt>'.$fn.'</tt>'; |
return '<br><b>Processed file:</b> <tt>'.$fn.'</tt>'; |
} |
} |
|
|
# ---------------------------- convert 'time' format into a datetime sql format |
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item sqltime |
|
|
|
Convert 'time' format into a datetime sql format |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub sqltime { |
sub sqltime { |
my $timef=shift @_; |
my $timef=shift @_; |
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = |
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = |
Line 156 sub sqltime {
|
Line 230 sub sqltime {
|
return "$year-$mon-$mday $hour:$min:$sec"; |
return "$year-$mon-$mday $hour:$min:$sec"; |
} |
} |
|
|
# --------------------------------------------------------- Various form fields |
|
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item Form field generating functions |
|
|
|
=over 4 |
|
|
|
=item textfield |
|
|
|
=item hiddenfield |
|
|
|
=item selectbox |
|
|
|
=back |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub textfield { |
sub textfield { |
my ($title,$name,$value)=@_; |
my ($title,$name,$value)=@_; |
return "\n<p><b>$title:</b><br>". |
return "\n<p><b>$title:</b><br>". |
Line 184 sub selectbox {
|
Line 278 sub selectbox {
|
return $selout.'</select>'; |
return $selout.'</select>'; |
} |
} |
|
|
# -------------------------------------------------------- Publication Step One |
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item urlfixup |
|
|
|
Fix up a url? First step of publication |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub urlfixup { |
sub urlfixup { |
my ($url,$target)=@_; |
my ($url,$target)=@_; |
unless ($url) { return ''; } |
unless ($url) { return ''; } |
Line 206 sub urlfixup {
|
Line 311 sub urlfixup {
|
return $url; |
return $url; |
} |
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item absoluteurl |
|
|
|
Currently undocumented |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub absoluteurl { |
sub absoluteurl { |
my ($url,$target)=@_; |
my ($url,$target)=@_; |
unless ($url) { return ''; } |
unless ($url) { return ''; } |
Line 217 sub absoluteurl {
|
Line 334 sub absoluteurl {
|
return $url; |
return $url; |
} |
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item set_allow |
|
|
|
Currently undocumented |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub set_allow { |
sub set_allow { |
my ($allow,$logfile,$target,$tag,$oldurl)=@_; |
my ($allow,$logfile,$target,$tag,$oldurl)=@_; |
my $newurl=&urlfixup($oldurl,$target); |
my $newurl=&urlfixup($oldurl,$target); |
Line 235 sub set_allow {
|
Line 365 sub set_allow {
|
return $return_url |
return $return_url |
} |
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item get_subscribed_hosts |
|
|
|
Currently undocumented |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub get_subscribed_hosts { |
sub get_subscribed_hosts { |
my ($target)=@_; |
my ($target)=@_; |
my @subscribed; |
my @subscribed; |
Line 268 sub get_subscribed_hosts {
|
Line 411 sub get_subscribed_hosts {
|
} |
} |
|
|
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item get_max_ids_indices |
|
|
|
Currently undocumented |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub get_max_ids_indices { |
sub get_max_ids_indices { |
my ($content)=@_; |
my ($content)=@_; |
my $maxindex=10; |
my $maxindex=10; |
Line 299 sub get_max_ids_indices {
|
Line 455 sub get_max_ids_indices {
|
return ($needsfixup,$maxid,$maxindex); |
return ($needsfixup,$maxid,$maxindex); |
} |
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item get_all_text_unbalanced |
|
|
|
Currently undocumented |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub get_all_text_unbalanced { |
sub get_all_text_unbalanced { |
#there is a copy of this in lonxml.pm |
#there is a copy of this in lonxml.pm |
my($tag,$pars)= @_; |
my($tag,$pars)= @_; |
Line 316 sub get_all_text_unbalanced {
|
Line 485 sub get_all_text_unbalanced {
|
$result.=$token->[2]; |
$result.=$token->[2]; |
} |
} |
if ($result =~ /(.*)$tag(.*)/) { |
if ($result =~ /(.*)$tag(.*)/) { |
&Apache::lonnet::logthis('Got a winner with leftovers ::'.$2); |
#&Apache::lonnet::logthis('Got a winner with leftovers ::'.$2); |
&Apache::lonnet::logthis('Result is :'.$1); |
#&Apache::lonnet::logthis('Result is :'.$1); |
$result=$1; |
$result=$1; |
my $redo=$tag.$2; |
my $redo=$tag.$2; |
push (@$pars,HTML::LCParser->new(\$redo)); |
push (@$pars,HTML::LCParser->new(\$redo)); |
Line 328 sub get_all_text_unbalanced {
|
Line 497 sub get_all_text_unbalanced {
|
return $result |
return $result |
} |
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item fix_ids_and_indices |
|
|
|
Currently undocumented |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
#Arguably this should all be done as a lonnet::ssi instead |
#Arguably this should all be done as a lonnet::ssi instead |
sub fix_ids_and_indices { |
sub fix_ids_and_indices { |
my ($logfile,$source,$target)=@_; |
my ($logfile,$source,$target)=@_; |
Line 381 sub fix_ids_and_indices {
|
Line 563 sub fix_ids_and_indices {
|
} |
} |
foreach my $type ('src','href','background','bgimg') { |
foreach my $type ('src','href','background','bgimg') { |
foreach my $key (keys(%parms)) { |
foreach my $key (keys(%parms)) { |
print $logfile "for $type, and $key\n"; |
|
if ($key =~ /^$type$/i) { |
if ($key =~ /^$type$/i) { |
print $logfile "calling set_allow\n"; |
|
$parms{$key}=&set_allow(\%allow,$logfile, |
$parms{$key}=&set_allow(\%allow,$logfile, |
$target,$tag, |
$target,$tag, |
$parms{$key}); |
$parms{$key}); |
Line 469 sub fix_ids_and_indices {
|
Line 649 sub fix_ids_and_indices {
|
return ($outstring,%allow); |
return ($outstring,%allow); |
} |
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item store_metadata |
|
|
|
Store the metadata in the metadata table in the loncapa database. |
|
Uses lonmysql to access the database. |
|
|
|
Inputs: \%metadata |
|
|
|
Returns: (error,status). error is undef on success, status is undef on error. |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
|
sub store_metadata { |
|
my %metadata = %{shift()}; |
|
my $error; |
|
# Determine if the table exists |
|
my $status = &Apache::lonmysql::check_table('metadata'); |
|
if (! defined($status)) { |
|
$error='<font color="red">WARNING: Cannot connect to '. |
|
'database!</font>'; |
|
&Apache::lonnet::logthis($error); |
|
return ($error,undef); |
|
} |
|
if ($status == 0) { |
|
# It would be nice to actually create the table.... |
|
$error ='<font color="red">WARNING: The metadata table does not '. |
|
'exist in the LON-CAPA database.</font>'; |
|
&Apache::lonnet::logthis($error); |
|
return ($error,undef); |
|
} |
|
# Remove old value from table |
|
$status = &Apache::lonmysql::remove_from_table |
|
('metadata','url',$metadata{'url'}); |
|
if (! defined($status)) { |
|
$error = '<font color="red">Error when removing old values from '. |
|
'metadata table in LON-CAPA database.</font>'; |
|
&Apache::lonnet::logthis($error); |
|
return ($error,undef); |
|
} |
|
# Store data in table. |
|
$status = &Apache::lonmysql::store_row('metadata',\%metadata); |
|
if (! defined($status)) { |
|
$error='<font color="red">Error occured storing new values in '. |
|
'metadata table in LON-CAPA database</font>'; |
|
&Apache::lonnet::logthis($error); |
|
return ($error,undef); |
|
} |
|
return (undef,$status); |
|
} |
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item publish |
|
|
|
Currently undocumented. This is the workhorse function of this module. |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub publish { |
sub publish { |
|
|
my ($source,$target,$style)=@_; |
my ($source,$target,$style)=@_; |
Line 788 END
|
Line 1037 END
|
'<p><input type="submit" value="Finalize Publication" /></p></form>'; |
'<p><input type="submit" value="Finalize Publication" /></p></form>'; |
} |
} |
|
|
# -------------------------------------------------------- Publication Step Two |
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item phasetwo |
|
|
|
Render second interface showing status of publication steps. |
|
This is publication step two. |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub phasetwo { |
sub phasetwo { |
|
|
my ($source,$target,$style,$distarget)=@_; |
my ($source,$target,$style,$distarget)=@_; |
Line 860 sub phasetwo {
|
Line 1121 sub phasetwo {
|
} |
} |
|
|
# -------------------------------- Synchronize entry with SQL metadata database |
# -------------------------------- Synchronize entry with SQL metadata database |
my $warning; |
my $warning; |
|
$metadatafields{'url'} = $distarget; |
unless ($metadatafields{'copyright'} eq 'priv') { |
$metadatafields{'version'} = 'current'; |
|
unless ($metadatafields{'copyright'} eq 'priv') { |
my $dbh; |
my ($error,$success) = &store_metadata(\%metadatafields); |
{ |
if ($success) { |
unless ( |
$scrout.='<p>Synchronized SQL metadata database'; |
$dbh = DBI->connect("DBI:mysql:loncapa","www", |
print $logfile "\nSynchronized SQL metadata database"; |
$Apache::lonnet::perlvar{'lonSqlAccess'},{ RaiseError =>0,PrintError=>0}) |
} else { |
) { |
$warning.=$error; |
$warning='<font color=red>WARNING: Cannot connect to '. |
print $logfile "\n".$error; |
'database!</font>'; |
} |
} |
} else { |
else { |
$scrout.='<p>Private Publication - did not synchronize database'; |
my %sqldatafields; |
print $logfile "\nPrivate: Did not synchronize data into ". |
$sqldatafields{'url'}=$distarget; |
"SQL metadata database"; |
my $sth=$dbh->prepare( |
|
'delete from metadata where url like binary'. |
|
'"'.$sqldatafields{'url'}.'"'); |
|
$sth->execute(); |
|
foreach ('title','author','subject','keywords','notes','abstract', |
|
'mime','language','creationdate','lastrevisiondate','owner', |
|
'copyright') { |
|
my $field=$metadatafields{$_}; $field=~s/\"/\'\'/g; |
|
$sqldatafields{$_}=$field; |
|
} |
|
|
|
$sth=$dbh->prepare('insert into metadata values ('. |
|
'"'.delete($sqldatafields{'title'}).'"'.','. |
|
'"'.delete($sqldatafields{'author'}).'"'.','. |
|
'"'.delete($sqldatafields{'subject'}).'"'.','. |
|
'"'.delete($sqldatafields{'url'}).'"'.','. |
|
'"'.delete($sqldatafields{'keywords'}).'"'.','. |
|
'"'.'current'.'"'.','. |
|
'"'.delete($sqldatafields{'notes'}).'"'.','. |
|
'"'.delete($sqldatafields{'abstract'}).'"'.','. |
|
'"'.delete($sqldatafields{'mime'}).'"'.','. |
|
'"'.delete($sqldatafields{'language'}).'"'.','. |
|
'"'. |
|
sqltime(delete($sqldatafields{'creationdate'})) |
|
.'"'.','. |
|
'"'. |
|
sqltime(delete( |
|
$sqldatafields{'lastrevisiondate'})).'"'.','. |
|
'"'.delete($sqldatafields{'owner'}).'"'.','. |
|
'"'.delete( |
|
$sqldatafields{'copyright'}).'"'.')'); |
|
$sth->execute(); |
|
$dbh->disconnect; |
|
$scrout.='<p>Synchronized SQL metadata database'; |
|
print $logfile "\nSynchronized SQL metadata database"; |
|
} |
|
} |
} |
|
|
} else { |
|
$scrout.='<p>Private Publication - did not synchronize database'; |
|
print $logfile "\nPrivate: Did not synchronize data into ". |
|
"SQL metadata database"; |
|
} |
|
# ----------------------------------------------------------- Copy old versions |
# ----------------------------------------------------------- Copy old versions |
|
|
if (-e $target) { |
if (-e $target) { |
Line 1054 if (-e $target) {
|
Line 1273 if (-e $target) {
|
|
|
} |
} |
|
|
# ================================================================ Main Handler |
|
|
|
|
######################################### |
|
######################################### |
|
|
|
=pod |
|
|
|
=item handler |
|
|
|
A basic outline of the handler subroutine follows. |
|
|
|
=over 4 |
|
|
|
=item Get query string for limited number of parameters |
|
|
|
=item Check filename |
|
|
|
=item File is there and owned, init lookup tables |
|
|
|
=item Start page output |
|
|
|
=item Individual file |
|
|
|
=item publish from $thisfn to $thistarget with $thisembstyle |
|
|
|
=back |
|
|
|
=cut |
|
|
|
######################################### |
|
######################################### |
sub handler { |
sub handler { |
my $r=shift; |
my $r=shift; |
|
|
Line 1212 unless ($ENV{'form.phase'} eq 'two') {
|
Line 1459 unless ($ENV{'form.phase'} eq 'two') {
|
1; |
1; |
__END__ |
__END__ |
|
|
=head1 NAME |
=pod |
|
|
Apache::lonpublisher - Publication Handler |
|
|
|
=head1 SYNOPSIS |
|
|
|
Invoked by /etc/httpd/conf/srm.conf: |
|
|
|
<Location /adm/publish> |
|
PerlAccessHandler Apache::lonacc |
|
SetHandler perl-script |
|
PerlHandler Apache::lonpublisher |
|
ErrorDocument 403 /adm/login |
|
ErrorDocument 404 /adm/notfound.html |
|
ErrorDocument 406 /adm/unauthorized.html |
|
ErrorDocument 500 /adm/errorhandler |
|
</Location> |
|
|
|
=head1 INTRODUCTION |
|
|
|
This module publishes a file. This involves gathering metadata, |
|
versioning the file, copying file from construction space to |
|
publication space, and copying metadata from construction space |
|
to publication space. |
|
|
|
This is part of the LearningOnline Network with CAPA project |
|
described at http://www.lon-capa.org. |
|
|
|
=head1 HANDLER SUBROUTINE |
|
|
|
This routine is called by Apache and mod_perl. |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
Get query string for limited number of parameters |
|
|
|
=item * |
|
|
|
Check filename |
|
|
|
=item * |
|
|
|
File is there and owned, init lookup tables |
|
|
|
=item * |
|
|
|
Start page output |
|
|
|
=item * |
|
|
|
Individual file |
|
|
|
=item * |
|
|
|
publish from $thisfn to $thistarget with $thisembstyle |
|
|
|
=back |
|
|
|
=head1 OTHER SUBROUTINES |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
metaeval() : Evaluate string with metadata |
|
|
|
=item * |
|
|
|
metaread() : Read a metadata file |
|
|
|
=item * |
|
|
|
sqltime() : convert 'time' format into a datetime sql format |
|
|
|
=item * |
|
|
|
textfield() : form field |
|
|
|
=item * |
|
|
|
hiddenfield() : form field |
|
|
|
=item * |
|
|
|
selectbox() : form field |
|
|
|
=item * |
|
|
|
urlfixup() : fixup URL (Publication Step One) |
|
|
|
=item * |
|
|
|
publish() : publish (Publication Step One) |
|
|
|
=item * |
|
|
|
phasetwo() : render second interface showing status of publication steps |
|
(Publication Step Two) |
|
|
|
=back |
=back |
|
|
=cut |
=cut |
|
|