Rewrote all the command line utilities.
This commit is contained in:
parent
3ead160201
commit
505aa5809c
9 changed files with 505 additions and 349 deletions
|
|
@ -68,6 +68,9 @@ save you many hours of grief.
|
|||
sbin/Hourly as it is no longer required, and will cause
|
||||
problems if it is not removed.
|
||||
|
||||
* imageCollateralImport.pl has been replaced by collateralImport.pl.
|
||||
Please delete imageCollateralImport.pl.
|
||||
|
||||
|
||||
5.1.0
|
||||
--------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ These methods are available from this class:
|
|||
#-------------------------------------------------------------------
|
||||
# extended only to save info to database
|
||||
sub createThumbnail {
|
||||
$_[0]->SUPER::createThumbnail(@_);
|
||||
$_[0]->SUPER::createThumbnail($_[1]);
|
||||
if ($_[1] != $_[0]->get("thumbnailSize")) {
|
||||
$_[0]->set({thumbnailSize=>$_[1]});
|
||||
}
|
||||
|
|
|
|||
194
sbin/collateralImport.pl
Normal file
194
sbin/collateralImport.pl
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot, $webUser, @nailable);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "..";
|
||||
@nailable = qw(jpg jpeg png gif);
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
|
||||
$| = 1;
|
||||
|
||||
use Getopt::Long;
|
||||
use strict;
|
||||
use WebGUI::Collateral;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::SQL;
|
||||
use WebGUI::Utility;
|
||||
|
||||
|
||||
my $configFile;
|
||||
my $folderId;
|
||||
my $help;
|
||||
my $override;
|
||||
my $pathToFiles;
|
||||
my $quiet;
|
||||
my $thumbnailSize;
|
||||
my $webUser = 'apache';
|
||||
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'folderId=i'=>\$folderId,
|
||||
'help'=>\$help,
|
||||
'override'=>$override,
|
||||
'pathToFiles=s'=>\$pathToFiles,
|
||||
'quiet'=>\$quiet,
|
||||
'thumbnailSize=i'=>\$thumbnailSize,
|
||||
'webUser=s'=>\$webUser
|
||||
);
|
||||
|
||||
|
||||
if ($help || $configFile eq "" || $pathToFiles eq ""){
|
||||
print <<STOP;
|
||||
|
||||
|
||||
Usage: perl $0 --pathToFiles=<pathToImportFiles> --configfile=<webguiConfig>
|
||||
|
||||
--configFile WebGUI config file.
|
||||
|
||||
--pathToFiles Folder containing files to import.
|
||||
|
||||
|
||||
Options:
|
||||
|
||||
--folderId The unique identifier for the collateral
|
||||
folder that the imported files should
|
||||
be organized under. Defaults to '0' (Root).
|
||||
|
||||
--help Display this help message and exit.
|
||||
|
||||
--override This utility is designed to be run as
|
||||
a privileged user on Linux style systems.
|
||||
If you wish to run this utility without
|
||||
being the super user, then use this flag,
|
||||
but note that it may not work as
|
||||
intended.
|
||||
|
||||
--quiet Disable output unless there's an error.
|
||||
|
||||
--thumbnailSize The size (in pixels) of the thumbnails
|
||||
that will be generated if you import
|
||||
images. Defaults to the Thumbnail Size
|
||||
setting in the site's content settings.
|
||||
|
||||
--webUser The user that your web server runs as.
|
||||
Defaults to 'apache'.
|
||||
|
||||
STOP
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!($^O =~ /^Win/i) && $> != 0 && !$override) {
|
||||
print "You must be the super user to use this utility.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
print "Starting..." unless ($quiet);
|
||||
WebGUI::Session::open($webguiRoot,$ARGV[1]);
|
||||
WebGUI::Session::refreshUserInfo(3);
|
||||
print "OK\n" unless ($quiet);
|
||||
|
||||
addFiles(buildFileList($pathToFiles), ($thumbnailSize||$session{setting}{thumbnailSize}));
|
||||
setPrivileges();
|
||||
|
||||
print "Cleaning up..." unless ($quiet);
|
||||
WebGUI::Session::end($session{var}{sessionId});
|
||||
WebGUI::Session::close();
|
||||
print "OK\n" unless ($quiet);
|
||||
|
||||
|
||||
#-----------------------------------------
|
||||
# addFiles(dbHandler, filelistHashRef, webguiSettingsHashRef, pathToCopyFrom)
|
||||
#-----------------------------------------
|
||||
sub addFiles {
|
||||
my ($type, $parameters);
|
||||
my ($filelist, $thumbnailSize) = @_;
|
||||
print "Adding files...\n" unless ($quiet);
|
||||
foreach my $filename (keys %{$filelist}) {
|
||||
print "Processing $filename.\n" unless ($quiet);
|
||||
foreach my $ext (keys %{${$filelist}{$filename}}) {
|
||||
my $collateral = WebGUI::Collateral->new("new");
|
||||
print "\tCopying ".${$filelist}{$filename}{$ext}.".\n" unless ($quiet);
|
||||
$collateral->saveFromFilesystem($pathToFiles.$session{os}{slash}.${$filelist}{$filename}{$ext},$thumbnailSize);
|
||||
print "\tAdding $filename to the database.\n" unless ($quiet);
|
||||
if (isIn($ext, @nailable)) {
|
||||
$type = "image";
|
||||
$parameters = 'border="0"';
|
||||
} else {
|
||||
$type = "file";
|
||||
$parameters = '';
|
||||
}
|
||||
$collateral->set({
|
||||
collateralType=>$type,
|
||||
name=>$filelist->{$filename}{$ext},
|
||||
username=>"Imported",
|
||||
thumbnailSize=>$thumbnailSize,
|
||||
collateralFolderId=>$folderId,
|
||||
parameters=>$parameters
|
||||
});
|
||||
}
|
||||
}
|
||||
print "Finished adding.\n";
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------
|
||||
# setPrivileges()
|
||||
#-----------------------------------------
|
||||
sub setPrivileges {
|
||||
print "Setting filesystem privileges.\n" unless ($quiet);
|
||||
if ($session{os}{type} = "Linuxish") {
|
||||
unless (system("chown -R ".$webUser." ".$session{config}{uploadsPath})) {
|
||||
print "Privileges set.\n" unless ($quiet);
|
||||
} else {
|
||||
print "Could not set privileges.\n";
|
||||
}
|
||||
} else {
|
||||
print "Cannot set privileges on this platform.\n" unless ($quiet)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------
|
||||
# buildFileList(pathToImportFiles)
|
||||
#-----------------------------------------
|
||||
sub buildFileList {
|
||||
print "Building file list.\n" unless ($quiet);
|
||||
my (%filelist, @files, $file, $filename, $ext);
|
||||
if (opendir(FILES,$_[0])) {
|
||||
@files = readdir(FILES);
|
||||
foreach $file (@files) {
|
||||
unless ($file eq "." || $file eq "..") {
|
||||
$file =~ /(.*?)\.(.*?)$/;
|
||||
$filename = $1;
|
||||
$ext = $2;
|
||||
$filelist{$filename}{$ext} = $file;
|
||||
print "Found file $file.\n" unless ($quiet);
|
||||
}
|
||||
}
|
||||
closedir(FILES);
|
||||
print "File list complete.\n" unless ($quiet);
|
||||
return \%filelist;
|
||||
} else {
|
||||
print "Error: Could not open folder.\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -8,153 +10,172 @@
|
|||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot, $webUser, @nailable);
|
||||
our ($webguiRoot, @nailable);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "..";
|
||||
$webUser = "apache";
|
||||
@nailable = qw(jpg jpeg png gif tif tiff bmp);
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# NO NEED TO MODIFY BELOW THIS LINE
|
||||
|
||||
|
||||
|
||||
$| = 1;
|
||||
|
||||
use File::stat;
|
||||
use Image::Magick;
|
||||
use DBI;
|
||||
use Mysql;
|
||||
use Data::Config;
|
||||
use WebGUI::SQL;
|
||||
use File::Copy qw(cp);
|
||||
use File::Path;
|
||||
use File::stat;
|
||||
use FileHandle;
|
||||
use Getopt::Long;
|
||||
use Image::Magick;
|
||||
use POSIX;
|
||||
use strict;
|
||||
use WebGUI::Attachment;
|
||||
use WebGUI::DateTime;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::SQL;
|
||||
use WebGUI::Utility;
|
||||
|
||||
my ($filelist, $dbh, $settings, $config);
|
||||
|
||||
if ($ARGV[0] ne "" && $ARGV[1] ne ""){
|
||||
print "Starting...\n";
|
||||
$filelist = buildFileList($ARGV[0]);
|
||||
$config = getConfig($ARGV[1]);
|
||||
$dbh = connectToDb($config);
|
||||
$settings = getSettings($dbh,$ARGV[3]);
|
||||
addFiles($dbh, $filelist, $settings, $ARGV[0], $ARGV[2], $config);
|
||||
setPrivileges($config) unless ($^O =~ /Win/i);
|
||||
print "Cleaning up...\n";
|
||||
$dbh->disconnect;
|
||||
print "Finished!\n";
|
||||
} else {
|
||||
print "Usage: $0 <pathToFiles> <webguiConfigFile> <wobjectId> [<thumbnailSize>]\n";
|
||||
my $configFile;
|
||||
my $groupToView = 2;
|
||||
my $help;
|
||||
my $pathToFiles;
|
||||
my $override;
|
||||
my $quiet;
|
||||
my $webUser = 'apache';
|
||||
my $wobjectId;
|
||||
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'groupToView=i'=>\$groupToView,
|
||||
'help'=>\$help,
|
||||
'override'=>$override,
|
||||
'pathToFiles=s'=>\$pathToFiles,
|
||||
'quiet'=>\$quiet,
|
||||
'webUser=s'=>\$webUser,
|
||||
'wobjectId=i'=>\$wobjectId
|
||||
);
|
||||
|
||||
|
||||
if ($help || $configFile eq "" || $pathToFiles eq "" || $wobjectId eq ""){
|
||||
print <<STOP;
|
||||
|
||||
|
||||
Usage: perl $0 --pathToFiles=<pathToImportFiles> --configfile=<webguiConfig> --wobjectId=<fileManagerWobjectId>
|
||||
|
||||
--configFile WebGUI config file.
|
||||
|
||||
--pathToFiles Folder containing files to import.
|
||||
|
||||
--wobjectId The wobject ID of the file manager you
|
||||
wish to import these files to.
|
||||
|
||||
|
||||
Options:
|
||||
|
||||
--groupToView The group ID of the group that should
|
||||
have the privileges to view these
|
||||
files. Defaults to '2'.
|
||||
|
||||
--help Display this help message and exit.
|
||||
|
||||
--override This utility is designed to be run as
|
||||
a privileged user on Linux style systems.
|
||||
If you wish to run this utility without
|
||||
being the super user, then use this flag,
|
||||
but note that it may not work as
|
||||
intended.
|
||||
|
||||
--quiet Disable output unless there's an error.
|
||||
|
||||
--webUser The user that your web server runs as.
|
||||
Defaults to 'apache'.
|
||||
|
||||
STOP
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!($^O =~ /^Win/i) && $> != 0 && !$override) {
|
||||
print "You must be the super user to use this utility.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
print "Starting..." unless ($quiet);
|
||||
WebGUI::Session::open($webguiRoot,$ARGV[1]);
|
||||
WebGUI::Session::refreshUserInfo(3);
|
||||
print "OK\n" unless ($quiet);
|
||||
|
||||
addFiles(buildFileList($pathToFiles));
|
||||
setPrivileges();
|
||||
|
||||
print "Cleaning up..." unless ($quiet);
|
||||
WebGUI::Session::end($session{var}{sessionId});
|
||||
WebGUI::Session::close();
|
||||
print "OK\n" unless ($quiet);
|
||||
|
||||
#-----------------------------------------
|
||||
# addFiles(dbHandler, filelistHashRef, webguiSettingsHashRef, pathToCopyFrom)
|
||||
#-----------------------------------------
|
||||
sub addFiles {
|
||||
my ($exists, @files, $filename, $ext, $id, $i, $file1, $file2, $file3, $seq);
|
||||
print "Adding files...\n";
|
||||
($exists) = WebGUI::SQL->quickArray("select count(*) from FileManager where wobjectId='$_[4]'",$_[0]);
|
||||
print "Adding files...\n" unless ($quiet);
|
||||
($exists) = WebGUI::SQL->quickArray("select count(*) from FileManager where wobjectId='$wobjectId'");
|
||||
if ($exists) {
|
||||
mkdir($_[5]->{uploadsPath}."/".$_[4]);
|
||||
foreach $filename (keys %{$_[1]}) {
|
||||
print "Processing $filename.\n";
|
||||
$id = getId($_[0]);
|
||||
mkdir($_[5]->{uploadsPath}."/".$_[4]."/".$id);
|
||||
($seq) = WebGUI::SQL->quickArray("select max(sequenceNumber) from FileManager_file where wobjectId='$_[4]'",$_[0]);
|
||||
my $w = WebGUI::Wobject::FileManager->new({wobjectId=>$wobjectId,namespace=>"FileManager"});
|
||||
foreach $filename (keys %{$_[0]}) {
|
||||
print "Processing $filename.\n" unless ($quiet);
|
||||
$i = 0;
|
||||
@files = [];
|
||||
foreach $ext (keys %{${$_[1]}{$filename}}) {
|
||||
print "Copying ".${$_[1]}{$filename}{$ext}.".\n";
|
||||
$a = FileHandle->new($_[3]."/".${$_[1]}{$filename}{$ext},"r");
|
||||
binmode($a);
|
||||
$b = FileHandle->new(">".$_[5]->{uploadsPath}."/".$_[4]."/".$id."/".${$_[1]}{$filename}{$ext});
|
||||
binmode($b);
|
||||
cp($a,$b);
|
||||
$a->close;
|
||||
$b->close;
|
||||
createThumbnail(${$_[1]}{$filename}{$ext},$_[5]->{uploadsPath}."/".$_[4]."/".$id,$_[2]->{thumbnailSize});
|
||||
$files[$i] = ${$_[1]}{$filename}{$ext};
|
||||
print "\tAdding $filename to the database.\n" unless ($quiet);
|
||||
my $fileId = $w->setCollateral("FileManager_file","FileManager_fileId",{
|
||||
FileManager_fileId=>"new",
|
||||
groupToView=>$groupToView,
|
||||
dateUploaded=>time(),
|
||||
fileTitle=>$filename
|
||||
});
|
||||
my $attachment = WebGUI::Attachment->new("new",$w->get("wobjectId"),$fileId);
|
||||
foreach $ext (keys %{${$_[0]}{$filename}}) {
|
||||
print "\tCopying ".${$_[0]}{$filename}{$ext}.".\n" unless ($quiet);
|
||||
$attachment->saveFromFilesystem($pathToFiles.$session{os}{slash}.${$_[0]}{$filename}{$ext});
|
||||
$files[$i] = ${$_[0]}{$filename}{$ext};
|
||||
$i++;
|
||||
}
|
||||
my @files = sort {isIn(getType($b),@nailable) cmp isIn(getType($a),@nailable)} @files;
|
||||
print "Adding $filename to the database.\n";
|
||||
WebGUI::SQL->write("insert into FileManager_file (FileManager_fileId,wobjectId,fileTitle,downloadFile,
|
||||
groupToView,dateUploaded,alternateVersion1,alternateVersion2,sequenceNumber) values (
|
||||
$id,$_[4],'$filename','$files[0]',2,".time().",'$files[1]','$files[2]',".($seq+1).")",$_[0]);
|
||||
$w->setCollateral("FileManager_file","FileManager_fileId",{
|
||||
FileManager_fileId=>$fileId,
|
||||
downloadFile=>$files[0],
|
||||
alternateVersion1=>$files[1],
|
||||
alternateVersion2=>$files[2]
|
||||
});
|
||||
}
|
||||
} else {
|
||||
print "Warning: File Manager '$_[4]' does not exist. Cannot import files.\n";
|
||||
print "Warning: File Manager '".$wobjectId."' does not exist. Cannot import files.\n";
|
||||
}
|
||||
print "Finished adding.\n";
|
||||
print "Finished adding.\n" unless ($quiet);
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# setPrivileges(webguiSettingsHashRef)
|
||||
# setPrivileges()
|
||||
#-----------------------------------------
|
||||
sub setPrivileges {
|
||||
print "Setting filesystem privileges.\n";
|
||||
system("chown -R ".$webUser." ".$_[0]->{uploadsPath});
|
||||
print "Privileges set.\n";
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# getSettings(dbHandler)
|
||||
#-----------------------------------------
|
||||
sub getSettings {
|
||||
my (%settings);
|
||||
print "Retrieving settings from WebGUI.\n";
|
||||
%settings = WebGUI::SQL->buildHash("select * from settings",$_[0]);
|
||||
print "Settings retrieved.\n";
|
||||
$settings{thumbnailSize} = $_[1] if ($_[1] ne "");
|
||||
return \%settings;
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# getConfig(configFilename)
|
||||
#-----------------------------------------
|
||||
sub getConfig {
|
||||
my ($config, $error, %config);
|
||||
print "Getting site config.\n";
|
||||
$config = new Data::Config $webguiRoot.'/etc/'.$_[0] or $error=1;
|
||||
if ($error) {
|
||||
print "Couldn't open config file.\n";
|
||||
exit;
|
||||
print "Setting filesystem privileges.\n" unless ($quiet);
|
||||
if ($session{os}{type} = "Linuxish") {
|
||||
unless (system("chown -R ".$webUser." ".$session{config}{uploadsPath})) {
|
||||
print "Privileges set.\n" unless ($quiet);
|
||||
} else {
|
||||
print "Could not set privileges.\n";
|
||||
}
|
||||
} else {
|
||||
foreach ($config->param) {
|
||||
$config{$_} = $config->param($_);
|
||||
}
|
||||
print "Config retrieved.\n";
|
||||
return \%config;
|
||||
print "Cannot set privileges on this platform.\n" unless ($quiet)
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# connectToDb()
|
||||
#-----------------------------------------
|
||||
sub connectToDb {
|
||||
my ($dbh, $error);
|
||||
print "Connecting to database ".${$_[0]}{dsn}." as user ".${$_[0]}{dbuser}.".\n";
|
||||
$dbh = DBI->connect(${$_[0]}{dsn}, ${$_[0]}{dbuser}, ${$_[0]}{dbpass}, { RaiseError => 0, AutoCommit => 1 }) or $error=1;
|
||||
unless ($error) {
|
||||
print "Connection established.\n";
|
||||
return $dbh;
|
||||
} else {
|
||||
print "Error: Could not connect to the database.\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# buildFileList(pathToImportFiles)
|
||||
#-----------------------------------------
|
||||
sub buildFileList {
|
||||
print "Building file list.\n";
|
||||
print "Building file list.\n" unless ($quiet);
|
||||
my (%filelist, @files, $file, $filename, $ext);
|
||||
if (opendir(FILES,$_[0])) {
|
||||
@files = readdir(FILES);
|
||||
|
|
@ -164,11 +185,11 @@ sub buildFileList {
|
|||
$filename = $1;
|
||||
$ext = $2;
|
||||
$filelist{$filename}{$ext} = $file;
|
||||
print "Found file $file.\n";
|
||||
print "Found file $file.\n" unless ($quiet);
|
||||
}
|
||||
}
|
||||
closedir(FILES);
|
||||
print "File list complete.\n";
|
||||
print "File list complete.\n" unless ($quiet);
|
||||
return \%filelist;
|
||||
} else {
|
||||
print "Error: Could not open folder.\n";
|
||||
|
|
@ -176,28 +197,6 @@ sub buildFileList {
|
|||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# isIn(keyvalue, arrayOfValues)
|
||||
#-----------------------------------------
|
||||
sub isIn {
|
||||
my ($i, @a, @b, @isect, %union, %isect, $e);
|
||||
foreach $e (@_) {
|
||||
if ($a[0] eq "") {
|
||||
$a[0] = $e;
|
||||
} else {
|
||||
$b[$i] = $e;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
foreach $e (@a, @b) { $union{$e}++ && $isect{$e}++ }
|
||||
@isect = keys %isect;
|
||||
if (defined @isect) {
|
||||
undef @isect;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# getType(filename)
|
||||
|
|
@ -209,37 +208,6 @@ sub getType {
|
|||
return $extension;
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# createThumbnail(filename,path,thumnailSize)
|
||||
#-----------------------------------------
|
||||
sub createThumbnail {
|
||||
my ($image, $x, $y, $r, $n, $type);
|
||||
$type = getType($_[0]);
|
||||
if (isIn($type, @nailable) && !($_[0] =~ m/thumb-/)) {
|
||||
print "Nailing: $_[1]/$_[0]\n";
|
||||
$image = Image::Magick->new;
|
||||
$image->Read($_[1].'/'.$_[0]);
|
||||
($x, $y) = $image->Get('width','height');
|
||||
$n = $_[2] || 50;
|
||||
$r = $x>$y ? $x / $n : $y / $n;
|
||||
$image->Scale(width=>($x/$r),height=>($y/$r)) if ($r > 0);
|
||||
if (isIn($type, qw(tif tiff bmp))) {
|
||||
$image->Write($_[1].'/thumb-'.$_[0].'.png');
|
||||
} else {
|
||||
$image->Write($_[1].'/thumb-'.$_[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# getId(dbHandler)
|
||||
#-----------------------------------------
|
||||
sub getId {
|
||||
my ($id);
|
||||
($id) = WebGUI::SQL->quickArray("select nextValue from incrementer where incrementerId='downloadId'",$_[0]);
|
||||
WebGUI::SQL->write("update incrementer set nextValue=nextValue+1 where incrementerId='downloadId'",$_[0]);
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,108 +0,0 @@
|
|||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot, $webUser, @nailable);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "..";
|
||||
$webUser = "apache";
|
||||
@nailable = qw(jpg jpeg png gif);
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# NO NEED TO MODIFY BELOW THIS LINE
|
||||
|
||||
|
||||
$| = 1;
|
||||
|
||||
use strict;
|
||||
use WebGUI::Attachment;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::SQL;
|
||||
use WebGUI::Utility;
|
||||
|
||||
if ($ARGV[0] ne "" && $ARGV[1] ne ""){
|
||||
print "Starting...\n";
|
||||
print "Establishing WebGUI Session...\n";
|
||||
WebGUI::Session::open($webguiRoot,$ARGV[1]);
|
||||
WebGUI::Session::refreshUserInfo(3);
|
||||
addFiles(buildFileList($ARGV[0]), $ARGV[0],($ARGV[2]||$session{setting}{thumbnailSize}));
|
||||
setPrivileges() unless ($session{os}{type} eq "Windowsish");
|
||||
print "Cleaning up...\n";
|
||||
WebGUI::Session::close();
|
||||
print "Finished!\n";
|
||||
} else {
|
||||
print "Usage: $0 <pathToNewImages> <webguiConfigFile> [<thumbnailSize>]\n";
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# addFiles(dbHandler, filelistHashRef, webguiSettingsHashRef, pathToCopyFrom)
|
||||
#-----------------------------------------
|
||||
sub addFiles {
|
||||
my ($filename, $ext, $id, $a, $b);
|
||||
my ($filelist, $pathToImages, $thumbnailSize) = @_;
|
||||
print "Adding files...\n";
|
||||
foreach $filename (keys %{$filelist}) {
|
||||
print "Processing $filename.\n";
|
||||
foreach $ext (keys %{${$filelist}{$filename}}) {
|
||||
$id = getNextId("collateralId");
|
||||
print "Copying ".${$filelist}{$filename}{$ext}.".\n";
|
||||
my $file = WebGUI::Attachment->new(${$filelist}{$filename}{$ext},"images",$id);
|
||||
$file->saveFromFilesystem($pathToImages."/".${$filelist}{$filename}{$ext},$thumbnailSize);
|
||||
print "Adding $filename to the database.\n";
|
||||
WebGUI::SQL->write("insert into collateral (collateralId,name,filename,userId,username,
|
||||
dateUploaded,collateralType,thumbnailsize) values
|
||||
($id,".quote($filename).",".quote($filename.".".$ext).",3,'Imported',".time().",
|
||||
'image',$thumbnailSize)");
|
||||
}
|
||||
}
|
||||
print "Finished adding.\n";
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# setPrivileges(webguiSettingsHashRef)
|
||||
#-----------------------------------------
|
||||
sub setPrivileges {
|
||||
print "Setting filesystem privileges.\n";
|
||||
system("chown -R ".$webUser." ".$session{config}{uploadsPath});
|
||||
print "Privileges set.\n";
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# buildFileList(pathToImportFiles)
|
||||
#-----------------------------------------
|
||||
sub buildFileList {
|
||||
print "Building file list.\n";
|
||||
my (%filelist, @files, $file, $filename, $ext);
|
||||
if (opendir(FILES,$_[0])) {
|
||||
@files = readdir(FILES);
|
||||
foreach $file (@files) {
|
||||
unless ($file eq "." || $file eq "..") {
|
||||
$file =~ /(.*?)\.(.*?)$/;
|
||||
$filename = $1;
|
||||
$ext = $2;
|
||||
if (isIn($ext, @nailable)) {
|
||||
$filelist{$filename}{$ext} = $file;
|
||||
print "Found file $file.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(FILES);
|
||||
print "File list complete.\n";
|
||||
return \%filelist;
|
||||
} else {
|
||||
print "Error: Could not open folder.\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -15,34 +17,14 @@
|
|||
|
||||
use File::stat;
|
||||
use Image::Magick;
|
||||
use lib "../lib";
|
||||
use WebGUI::Utility;
|
||||
|
||||
|
||||
if ($ARGV[0] ne ""){
|
||||
$results = recurseFileSystem($ARGV[0]);
|
||||
} else {
|
||||
print "Usage: $0 <uploadsPath> [<thumbnailSize (50)>]\n";
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
# isIn(string, listToCheck)
|
||||
#-----------------------------------------
|
||||
sub isIn {
|
||||
my ($i, @a, @b, @isect, %union, %isect, $e);
|
||||
foreach $e (@_) {
|
||||
if ($a[0] eq "") {
|
||||
$a[0] = $e;
|
||||
} else {
|
||||
$b[$i] = $e;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
foreach $e (@a, @b) { $union{$e}++ && $isect{$e}++ }
|
||||
@isect = keys %isect;
|
||||
if (defined @isect) {
|
||||
undef @isect;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
print "Usage: perl $0 <uploadsPath> [<thumbnailSize (50)>]\n";
|
||||
}
|
||||
|
||||
#-----------------------------------------
|
||||
|
|
|
|||
192
sbin/upgrade.pl
192
sbin/upgrade.pl
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -15,52 +17,117 @@ BEGIN {
|
|||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use DBI;
|
||||
use Getopt::Long;
|
||||
use Parse::PlainConfig;
|
||||
use strict;
|
||||
use WebGUI::SQL;
|
||||
|
||||
my $help;
|
||||
my $override;
|
||||
my $quiet;
|
||||
my $mysql = "/usr/bin/mysql";
|
||||
my $mysqldump = "/usr/bin/mysqldump";
|
||||
my $backupDir = "/data/backups";
|
||||
my $skipBackup;
|
||||
my $doit;
|
||||
|
||||
GetOptions(
|
||||
'help'=>\$help,
|
||||
'override'=>$override,
|
||||
'quiet'=>\$quiet,
|
||||
'mysql'=>\$mysql,
|
||||
'doit'=>\$doit,
|
||||
'mysqldump'=>\$mysqldump,
|
||||
'backupDir'=>\$backupDir,
|
||||
'skipbackup'=>\$skipBackup
|
||||
);
|
||||
|
||||
|
||||
if ($ARGV[0] ne "--doit") {
|
||||
print "\n";
|
||||
print "WebGUI Assisted Upgrade Utility\n";
|
||||
print "\n";
|
||||
print "There are no guarantees of any kind provided at this software. Use\n";
|
||||
print "it at your own risk. Always make frequent backups of your data.\n";
|
||||
print "\n";
|
||||
print "NOTE: This utility will work on MySQL databases only. Any\n";
|
||||
print "configs using non-MySQL databases will be skipped.\n";
|
||||
print "\n";
|
||||
print "By default WebGUI will use these settings to perform the\n";
|
||||
print "upgrades. You may override these settings on a per site basis\n";
|
||||
print "by adding the variables to each site's WebGUI config file.\n";
|
||||
print "\n";
|
||||
print "\tmysqlCLI = $mysql\n";
|
||||
print "\tmysqlDump = $mysqldump\n";
|
||||
print "\tbackupPath = $backupDir\n";
|
||||
print "\n";
|
||||
print "Use the following command to begin the upgrade.\n";
|
||||
print "\n";
|
||||
print "\tperl $0 --doit\n";
|
||||
print "\n";
|
||||
if ($help){
|
||||
print <<STOP;
|
||||
|
||||
|
||||
Usage: perl $0
|
||||
|
||||
Options:
|
||||
|
||||
--backupDir The folder where backups should be
|
||||
created. Defaults to '/data/backups'.
|
||||
|
||||
--help Display this help message and exit.
|
||||
|
||||
--mysql The path to your mysql client executable.
|
||||
Defaults to '/usr/bin/mysql'.
|
||||
|
||||
--mysqldump The path to your mysqldump executable.
|
||||
Defaults to '/usr/bin/mysqldump'.
|
||||
|
||||
--override This utility is designed to be run as
|
||||
a privileged user on Linux style systems.
|
||||
If you wish to run this utility without
|
||||
being the super user, then use this flag,
|
||||
but note that it may not work as
|
||||
intended.
|
||||
|
||||
--quiet Disable output unless there's an error.
|
||||
|
||||
--skipBackup Backups will not be performed during the
|
||||
upgrade.
|
||||
|
||||
STOP
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unless ($doit) {
|
||||
print <<STOP;
|
||||
|
||||
+--------------------------------------------------------------------+
|
||||
| |
|
||||
| W A R N I N G |
|
||||
| |
|
||||
+--------------------------------------------------------------------+
|
||||
| |
|
||||
| There are no guarantees of any kind provided with this software. |
|
||||
| This utility has been tested rigorously, and has performed without |
|
||||
| error or consequence in our labs, and on our production servers |
|
||||
| for more than a year. However, there is no substitute for a good |
|
||||
| backup of your software and data before performing any kind of |
|
||||
| upgrade. |
|
||||
| |
|
||||
| NOTE: This utility will work on MySQL databases only. Any |
|
||||
| configs using non-MySQL databases will be skipped. |
|
||||
| |
|
||||
+--------------------------------------------------------------------+
|
||||
| |
|
||||
| For more information about this utility type: |
|
||||
| |
|
||||
| perl upgrade.pl --help |
|
||||
| |
|
||||
+--------------------------------------------------------------------+
|
||||
| |
|
||||
| You must include the command line argument "--doit" in your |
|
||||
| command in order to bypass this message. |
|
||||
| |
|
||||
+--------------------------------------------------------------------+
|
||||
|
||||
STOP
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!($^O =~ /^Win/i) && $> != 0) {
|
||||
if (!($^O =~ /^Win/i) && $> != 0 && !$override) {
|
||||
print "You must be the super user to use this utility.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
use Data::Config;
|
||||
use DBI;
|
||||
use WebGUI::SQL;
|
||||
|
||||
$|=1;
|
||||
my ($upgrade, @files, $file, $dbh, $config, $dir, %upgrade, %config);
|
||||
|
||||
|
||||
print "\nLooking for upgrade files...\n";
|
||||
print "\nLooking for upgrade files...\n" unless ($quiet);
|
||||
if ($^O =~ /^Win/i) {
|
||||
$dir = $webguiRoot."\\docs\\upgrades\\";
|
||||
} else {
|
||||
|
|
@ -73,10 +140,10 @@ foreach $file (@files) {
|
|||
if ($file =~ /upgrade_(\d+\.\d+.\d+)-(\d+\.\d+\.\d+)\.(\w+)/) {
|
||||
if (checkVersion($1)) {
|
||||
if ($3 eq "sql") {
|
||||
print "Found upgrade script from $1 to $2.\n";
|
||||
print "\tFound upgrade script from $1 to $2.\n" unless ($quiet);
|
||||
$upgrade{$1}{sql} = $dir.$file;
|
||||
} elsif ($3 eq "pl") {
|
||||
print "Found upgrade executable from $1 to $2.\n";
|
||||
print "\tFound upgrade executable from $1 to $2.\n" unless ($quiet);
|
||||
$upgrade{$1}{pl} = $dir.$file;
|
||||
}
|
||||
$upgrade{$1}{from} = $1;
|
||||
|
|
@ -87,7 +154,7 @@ foreach $file (@files) {
|
|||
|
||||
|
||||
|
||||
print "\nGetting site configs...\n";
|
||||
print "\nGetting site configs...\n" unless ($quiet);
|
||||
if ($^O =~ /^Win/i) {
|
||||
$dir = $webguiRoot."\\etc\\";
|
||||
} else {
|
||||
|
|
@ -98,32 +165,34 @@ opendir (DIR,$dir) or die "Can't open $dir\n";
|
|||
closedir(DIR);
|
||||
foreach $file (@files) {
|
||||
if ($file =~ /(.*?)\.conf$/ && $file ne "some_other_site.conf") {
|
||||
print "Found $file.\n";
|
||||
print "\tFound $file.\n" unless ($quiet);
|
||||
$config{$file}{configFile} = $dir.$file;
|
||||
my $config = new Data::Config $config{$file}{configFile};
|
||||
$config{$file}{dsn} = $config->param('dsn');
|
||||
my $config = Parse::PlainConfig->new('DELIM' => '=',
|
||||
'FILE' => $config{$file}{configFile},
|
||||
'PURGE' => 1);
|
||||
$config{$file}{dsn} = $config->get('dsn');
|
||||
$config{$file}{dsn} =~ /DBI\:(\w+)\:(\w+).*/;
|
||||
if ($1 eq "mysql") {
|
||||
$config{$file}{db} = $2;
|
||||
$config{$file}{dbuser} = $config->param('dbuser');
|
||||
$config{$file}{dbpass} = $config->param('dbpass');
|
||||
$config{$file}{mysqlCLI} = $config->param('mysqlCLI');
|
||||
$config{$file}{mysqlDump} = $config->param('mysqlDump');
|
||||
$config{$file}{backupPath} = $config->param('backupPath');
|
||||
$config{$file}{dbuser} = $config->get('dbuser');
|
||||
$config{$file}{dbpass} = $config->get('dbpass');
|
||||
$config{$file}{mysqlCLI} = $config->get('mysqlCLI');
|
||||
$config{$file}{mysqlDump} = $config->get('mysqlDump');
|
||||
$config{$file}{backupPath} = $config->get('backupPath');
|
||||
$dbh = DBI->connect($config{$file}{dsn},$config{$file}{dbuser},$config{$file}{dbpass});
|
||||
($config{$file}{version}) = WebGUI::SQL->quickArray("select webguiVersion from webguiVersion
|
||||
order by dateApplied desc, webguiVersion desc limit 1",$dbh);
|
||||
$dbh->disconnect;
|
||||
} else {
|
||||
delete $config{$file};
|
||||
print "Skipping non-MySQL database.\n";
|
||||
print "\tSkipping non-MySQL database.\n" unless ($quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
print "\nREADY TO BEGIN UPGRADES\n";
|
||||
print "\nREADY TO BEGIN UPGRADES\n" unless ($quiet);
|
||||
|
||||
my $notRun = 1;
|
||||
|
||||
|
|
@ -134,22 +203,45 @@ foreach $config (keys %config) {
|
|||
mkdir($backupTo);
|
||||
while ($upgrade{$config{$config}{version}}{sql} ne "") {
|
||||
$upgrade = $upgrade{$config{$config}{version}}{from};
|
||||
print "\n".$config{$config}{db}." ".$upgrade{$upgrade}{from}."-".$upgrade{$upgrade}{to}."\n";
|
||||
print "\tBacking up $config{$config}{db} ($upgrade{$upgrade}{from}).\n";
|
||||
system($dumpcmd." -u".$config{$config}{dbuser}." -p".$config{$config}{dbpass}." --add-drop-table --databases ".$config{$config}{db}." > ".$backupTo."/".$config{$config}{db}."_".$upgrade{$upgrade}{from}.".sql");
|
||||
print "\tUpgrading to $upgrade{$upgrade}{to}.\n";
|
||||
system($clicmd." -u".$config{$config}{dbuser}." -p".$config{$config}{dbpass}." --database=".$config{$config}{db}." < ".$upgrade{$upgrade}{sql});
|
||||
unless ($skipBackup) {
|
||||
print "\n".$config{$config}{db}." ".$upgrade{$upgrade}{from}."-".$upgrade{$upgrade}{to}."\n" unless ($quiet);
|
||||
print "\tBacking up $config{$config}{db} ($upgrade{$upgrade}{from})..." unless ($quiet);
|
||||
my $cmd = $dumpcmd." -u".$config{$config}{dbuser}." -p".$config{$config}{dbpass}
|
||||
." --add-drop-table --databases ".$config{$config}{db}." > "
|
||||
.$backupTo."/".$config{$config}{db}."_".$upgrade{$upgrade}{from}.".sql";
|
||||
unless (system($cmd)) {
|
||||
print "OK\n" unless ($quiet);
|
||||
} else {
|
||||
print "Failed!\n" unless ($quiet);
|
||||
}
|
||||
}
|
||||
print "\tUpgrading to ".$upgrade{$upgrade}{to}."..." unless ($quiet);
|
||||
my $cmd = $clicmd." -u".$config{$config}{dbuser}." -p".$config{$config}{dbpass}
|
||||
." --database=".$config{$config}{db}." < ".$upgrade{$upgrade}{sql};
|
||||
unless (system($cmd)) {
|
||||
print "OK\n" unless ($quiet);
|
||||
} else {
|
||||
print "Failed!\n" unless ($quiet);
|
||||
}
|
||||
$config{$config}{version} = $upgrade{$upgrade}{to};
|
||||
$notRun = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($notRun) {
|
||||
print "\nNO UPGRADES NECESSARY\n";
|
||||
print "\nNO UPGRADES NECESSARY\n\n" unless ($quiet);
|
||||
} else {
|
||||
print "\nUPGRADES COMPLETE\n";
|
||||
print "Please restart your web server and test your sites.\n";
|
||||
print "\nNOTE: If you have not already done so, please consult\ndocs/gotcha.txt for possible upgrade complications.\n\n";
|
||||
unless ($quiet) {
|
||||
print <<STOP;
|
||||
|
||||
UPGRADES COMPLETE
|
||||
Please restart your web server and test your sites.
|
||||
|
||||
NOTE: If you have not already done so, please consult
|
||||
docs/gotcha.txt for possible upgrade complications.
|
||||
|
||||
STOP
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2003 Plain Black LLC.
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -38,6 +40,8 @@ my $ldapUrl;
|
|||
my $status = 'Active';
|
||||
my $expireOffset;
|
||||
my $expireUnits = 'seconds';
|
||||
my $override;
|
||||
my $quiet;
|
||||
|
||||
GetOptions(
|
||||
'usersfile=s'=>\$usersFile,
|
||||
|
|
@ -48,9 +52,11 @@ GetOptions(
|
|||
'password|identifier:s'=>\$defaultIdentifier,
|
||||
'groups:s'=>\$groups,
|
||||
'ldapUrl:s'=>\$ldapUrl,
|
||||
'quiet'=>\$quiet,
|
||||
'status:s'=>\$status,
|
||||
'expireOffset:i'=>\$expireOffset,
|
||||
'expireUnits:s'=>\$expireUnits
|
||||
'expireUnits:s'=>\$expireUnits,
|
||||
'override'=>\$override
|
||||
);
|
||||
|
||||
|
||||
|
|
@ -61,7 +67,7 @@ unless ($usersFile && $configFile && !$help) {
|
|||
print <<STOP;
|
||||
|
||||
|
||||
Usage: $0 --userfile=<pathToFile> --configfile=<webguiConfig>
|
||||
Usage: perl $0 --userfile=<pathToFile> --configfile=<webguiConfig>
|
||||
|
||||
--usersFile File containing import information.
|
||||
|
||||
|
|
@ -103,11 +109,20 @@ Options:
|
|||
for authentication. Can be overridden in
|
||||
the import file.
|
||||
|
||||
--override This utility is designed to be run as
|
||||
a privileged user on Linux style systems.
|
||||
If you wish to run this utility without
|
||||
being the super user, then use this flag,
|
||||
but note that it may not work as
|
||||
intended.
|
||||
|
||||
--password The default password to use when none is
|
||||
specified with the user. Defaults to
|
||||
'123qwe'. Can be overridden in the import
|
||||
file.
|
||||
|
||||
--quiet Disable output unless there's an error.
|
||||
|
||||
--status The user's account status. Defaults to
|
||||
'Active'. Other valid value is 'Deactivated'.
|
||||
|
||||
|
|
@ -147,11 +162,18 @@ STOP
|
|||
}
|
||||
|
||||
|
||||
print "Starting up...";
|
||||
if (!($^O =~ /^Win/i) && $> != 0 && !$override) {
|
||||
print "You must be the super user to use this utility.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
print "Starting up..." unless ($quiet);
|
||||
WebGUI::Session::open($webguiRoot,$configFile);
|
||||
WebGUI::Session::refreshUserInfo(3); # The script should run as admin.
|
||||
open(FILE,"<".$usersFile);
|
||||
print "OK\n";
|
||||
print "OK\n" unless ($quiet);
|
||||
|
||||
my $first = 1;
|
||||
my $lineNumber = 0;
|
||||
|
|
@ -197,11 +219,11 @@ while(<FILE>) {
|
|||
# process user
|
||||
my ($duplicate) = WebGUI::SQL->quickArray("select count(*) from users where username=".quote($user{username}));
|
||||
if ($user{username} eq "") {
|
||||
print "Skipping line $lineNumber.\n";
|
||||
print "Skipping line $lineNumber.\n" unless ($quiet);
|
||||
} elsif ($duplicate) {
|
||||
print "User $user{username} already exists. Skipping.\n";
|
||||
print "User $user{username} already exists. Skipping.\n" unless ($quiet);
|
||||
} else {
|
||||
print "Adding user $user{username}\n";
|
||||
print "Adding user $user{username}\n" unless ($quiet);
|
||||
my $u = WebGUI::User->new("new");
|
||||
$u->username($user{username});
|
||||
$u->authMethod($user{authMethod});
|
||||
|
|
@ -223,10 +245,11 @@ while(<FILE>) {
|
|||
}
|
||||
}
|
||||
}
|
||||
print "Cleaning up...";
|
||||
print "Cleaning up..." unless ($quiet);
|
||||
close(FILE);
|
||||
WebGUI::Session::end($session{var}{sessionId});
|
||||
WebGUI::Session::close();
|
||||
print "OK\n";
|
||||
print "OK\n" unless ($quiet);
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue