diff options
Diffstat (limited to 'lib/gcstar/GCCommandLine.pm')
-rw-r--r-- | lib/gcstar/GCCommandLine.pm | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/lib/gcstar/GCCommandLine.pm b/lib/gcstar/GCCommandLine.pm new file mode 100644 index 0000000..17d2cf3 --- /dev/null +++ b/lib/gcstar/GCCommandLine.pm @@ -0,0 +1,395 @@ +package GCCommandLine; + +################################################### +# +# Copyright 2005-2010 Christian Jodar +# +# This file is part of GCstar. +# +# GCstar is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# GCstar is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCstar; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +# +################################################### + +use strict; + +{ + package GCPseudoFrame; + + use File::Basename; + use File::Temp qw(tempdir); + use GCUtils; + + sub new + { + my ($proto, $parent, $options, $lang, $keepPictures) = @_; + my $class = ref($proto) || $proto; + my $self = { + options => $options, + imagePrefix => 'gcstar_', + lang => $lang, + parent => $parent, + agent => 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20041111 Firefox/1.0', + }; + bless ($self, $class); + $self->{tmpImageDir} = tempdir(CLEANUP => ($keepPictures ? 0 : 1)); + return $self; + } + + sub setCurrentModel + { + my ($self, $model) = @_; + return $self->{parent}->setModel($model); + } + + sub transformTitle + { + my ($self, $title) = @_; + return $title; + } + + sub getImagesDir + { + my ($self, $suffix, $itemTitle, $imagesDir) = @_; + return GCFrame::getImagesDir(@_); + } + + sub getUniqueImageFileName + { + my ($self, $suffix, $itemTitle, $imagesDir) = @_; + return GCFrame::getUniqueImageFileName(@_); + } + + sub transformPicturePath + { + my ($self, $path, $file) = @_; + return GCFrame::transformPicturePath(@_); + } + + sub preloadModel + { + my ($self, $model) = @_; + # Preload the model into the factory cache + $self->{model} = $self->{modelsFactory}->getModel($model); + } + + sub AUTOLOAD + { + our $AUTOLOAD; + (my $name = $AUTOLOAD) =~ s/.*?::(.*)/$1/; + } +} + +{ + + package GCCommandExecution; + + use File::Temp qw/ :POSIX /; + use File::Basename; + use GCData; + use GCDisplay; + use GCExport; + use GCImport; + use GCPlugins; + use GCModel; + + sub new + { + my ($proto, $options, $model, $plugin, $import, $export, $output) = @_; + my $class = ref($proto) || $proto; + my $self = {}; + bless ($self, $class); + + $self->{file} = $output; + $self->{useStdOut} = 0; + if (!$output) + { + (undef, $self->{file}) = tmpnam; + $self->{useStdOut} = 1; + } + + GCPlugins::loadAllPlugins; + $self->{lang} = $GCLang::langs{$options->lang}; + $self->{parent} = new GCPseudoFrame($self, $options, $self->{lang}, $self->{useStdOut}); + + $self->{modelsFactory} = new GCModelsCache($self->{parent}); + $self->{model} = $self->{modelsFactory}->getModel($model); + $self->{parent}->{model} = $self->{model}; + $self->{parent}->{modelsFactory} = $self->{modelsFactory}; + + $self->{plugin} = $pluginsMap{$model}->{$plugin}; + $self->leave("Fetch plugin $plugin doesn't exist") if $plugin && (!$self->{plugin}); + + if ($import) + { + GCImport::loadImporters; + foreach (@importersArray) + { + $_->setLangName($options->lang); + if (($_->getName =~ /\Q$import/) || ($_ =~ /GCExport::GCExporter$export/)) + { + $self->{importer} = $_; + last; + } + } + $self->leave("Import plugin $import doesn't exist") if $import && (!$self->{importer}); + $self->{importer}->setModel($self->{model}); + $self->{importOptions} = {}; + foreach (@{$self->{importer}->getOptions}) + { + $self->{importOptions}->{$_->{name}} = $_->{default}; + } + } + if ($export) + { + GCExport::loadExporters; + foreach (@exportersArray) + { + $_->setLangName($options->lang); + if (($_->getName eq $export) || ($_ =~ /GCExport::GCExporter$export/)) + { + $self->{exporter} = $_; + last; + } + } + $self->leave("Export plugin $export doesn't exist") if $export && (!$self->{exporter}); + $self->{exporter}->setModel($self->{model}); + $self->{exportOptions} = { + lang => $self->{lang} + }; + foreach (@{$self->{exporter}->getOptions}) + { + $self->{exportOptions}->{$_->{name}} = $_->{default}; + } + } + + $self->{toBeRemoved} = []; + + $self->{data} = new GCItems($self->{parent}); + $self->{data}->{options} = $options; + + return $self; + } + + sub DESTROY + { + my $self = shift; + + unlink $_ foreach (@{$self->{toBeRemoved}}); + } + + sub leave + { + my ($self, $message) = @_; + print "$message\n"; + $self->DESTROY; + exit 1; + } + + sub listPlugins + { + my $self = shift; + + foreach (sort keys %{$pluginsMap{$self->{model}->getName}}) + { + print "$_\n"; + print "\t", $pluginsMap{$self->{model}->getName}->{$_}->getAuthor,"\n"; + print "\n"; + } + } + + sub setModel + { + my ($self, $model) = @_; + $self->{model} = $self->{modelsFactory}->getModel($model); + if ($self->{exporter}) + { + $self->{exporter}->setModel($self->{model}); + foreach (@{$self->{exporter}->getOptions}) + { + $self->{exportOptions}->{$_->{name}} = $_->{default}; + } + } + if ($self->{importer}) + { + $self->{importer}->setModel($self->{model}); + foreach (@{$self->{importer}->getOptions}) + { + $self->{importOptions}->{$_->{name}} = $_->{default}; + } + } + return 1; + } + + sub setFields + { + my ($self, $fieldsFile) = @_; + + $self->{fields} = []; + open FIELDS, '<'.$fieldsFile; + my $model = <FIELDS>; + chop $model; + while (<FIELDS>) + { + chop; + push @{$self->{fields}}, $_; + } + } + + sub load + { + my ($self, $title) = @_; + my @data; + $self->leave("No fetch plugin specified") if !$self->{plugin}; + $self->{plugin}->{title} = $title; + $self->{plugin}->{type} = 'load'; + $self->{plugin}->{urlField} = $self->{model}->{commonFields}->{url}; + $self->{plugin}->load; + my $itemNumber = $self->{plugin}->getItemsNumber(); + $self->{plugin}->{type} = 'info'; + for (my $i = 0; + $i < $itemNumber; + $i++) + { + $self->{plugin}->{wantedIdx} = $i; + my $info = $self->{plugin}->getItemInfo; + foreach (@{$self->{model}->{managedImages}}) + { + $info->{$_} = $self->downloadPicture($info->{$_}); + } + push @data, $info; + } + $self->{data}->setItemsList(\@data); + } + + sub save + { + my $self = shift; + my $previousFile = $self->{data}->{options}->file; + my $previousRelativePaths = $self->{data}->{options}->useRelativePaths; + my $prevImages = $self->{parent}->getImagesDir; + + + my $newFile = GCUtils::pathToUnix(File::Spec->rel2abs($self->{file})); + $self->{data}->{options}->file($newFile); + $self->{parent}->{file} = $newFile; + + # We re-generate it because it could have changed with new file name + my $newImages = $self->{parent}->getImagesDir; + if ($prevImages ne $newImages) + { + # The last parameter is for copy. When saving a new file, we move. + $self->{data}->setNewImagesDirectory($newImages, $prevImages, 1); + } + + $self->{data}->{model} = $self->{model}; + $self->{data}->{backend} = new GCBackend::GCBeXmlParser($self->{parent}) + if ! $self->{data}->{backend}; + $self->{data}->{options}->useRelativePaths(0) if $self->{useStdOut}; + $self->{data}->save; + $self->{data}->{options}->useRelativePaths($previousRelativePaths); + $self->{data}->{options}->file($previousFile); + open IN, $self->{file}; + if ($self->{useStdOut}) + { + print $_ while (<IN>); + } + close IN; + unlink $self->{file} if $self->{useStdOut}; + } + + sub open + { + my ($self, $file) = @_; + $self->{data}->load($file, undef, undef, 1); + $self->{original} = $file; + } + + sub import + { + my ($self, $file, $prefs) = @_; + $self->{importOptions}->{parent} = $self->{parent}; + $self->{importOptions}->{file} = $file; + $self->{importOptions}->{fields} = $self->{fields}; + $self->parsePrefs($prefs, $self->{importOptions}); + $self->{importer}->{options} = $self->{importOptions}; + $self->{data}->setItemsList($self->{importer}->getItemsArray($file)); + $self->setModel($self->{importer}->getModelName); + $self->{data}->{model} = $self->{model} + if $self->{data}; + } + + sub export + { + my ($self, $prefs) = @_; + + if (!scalar $self->{fields}) + { + $self->{fields} = $self->{model}->{fieldsNames}; + } + $self->{exportOptions}->{parent} = $self->{parent}; + $self->{exportOptions}->{fields} = $self->{fields}; + $self->{exportOptions}->{originalList} = $self->{data}; + $self->{exportOptions}->{withPictures} = 1; + $self->{exportOptions}->{file} = $self->{file}; + $self->{exportOptions}->{collection} = $self->{original}; + $self->{exportOptions}->{fieldsInfo} = $self->{model}->{fieldsInfo}; + $self->{exportOptions}->{items} = $self->{data}->getItemsListFiltered; + $self->{exportOptions}->{defaultImage} = $ENV{GCS_SHARE_DIR}.'/logos/no.png'; + $self->parsePrefs($prefs, $self->{exportOptions}); + $self->{data}->{model} = $self->{model} + if $self->{data}; + + $self->{exporter}->process($self->{exportOptions}); + + CORE::open IN, $self->{exportOptions}->{file}; + if ($self->{useStdOut}) + { + print $_ while (<IN>); + } + close IN; + unlink $self->{exportOptions}->{file} if $self->{useStdOut}; + } + + sub downloadPicture + { + my ($self, $pictureUrl) = @_; + + return '' if ! $pictureUrl; + my ($name,$path,$suffix) = fileparse($pictureUrl, "\.gif", "\.jpg", "\.jpeg", "\.png"); + (undef, my $picture) = tmpnam; + $picture .= $suffix; + + GCUtils::downloadFile($pictureUrl, $picture, $self->{parent}); + push @{$self->{toBeRemoved}}, $picture; + return $picture; + } + + sub parsePrefs + { + my ($self, $prefs, $cont) = @_; + + foreach (split /,/, $prefs) + { + my @option = split /=>/, $_; + $option[0] =~ s/^\s*//g; + $option[0] =~ s/\s*$//g; + $option[1] =~ s/^\s*//g; + $option[1] =~ s/\s*$//g; + $cont->{$option[0]} = $option[1]; + } + } +} + +1; |