source: gs2-extensions/open-office/trunk/src/perllib/plugins/OpenOfficeConverter.pm@ 23735

Last change on this file since 23735 was 23735, checked in by ak19, 13 years ago

Second (final) part of allowing user to set which port Jodconverter uses to communicate with soffice. By default this is set to 2002 internal to jodconverter, but it conflicts with programs (like logmein) which use this port, so that jodconverter can fail unless the user is given the ability to change the port it uses.

  • Property svn:executable set to *
File size: 9.8 KB
Line 
1###########################################################################
2#
3# OpenOfficeConverter - helper plugin that does office document conversion
4# using jodconverter combined with OpenOffice
5#
6# A component of the Greenstone digital library software
7# from the New Zealand Digital Library Project at the
8# University of Waikato, New Zealand.
9#
10# Copyright (C) 2010 New Zealand Digital Library Project
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program; if not, write to the Free Software
24# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25#
26###########################################################################
27package OpenOfficeConverter;
28
29use ConvertBinaryFile;
30use BaseMediaConverter;
31
32use strict;
33no strict 'refs'; # allow filehandles to be variables and viceversa
34
35use gsprintf 'gsprintf';
36
37# these two variables mustn't be initialised here or they will get stuck
38# at those values.
39our $openoffice_conversion_available;
40our $no_openoffice_conversion_reason;
41
42BEGIN {
43 @OpenOfficeConverter::ISA = ('BaseMediaConverter');
44
45 # Check that OpenOffice and jodconverter are installed and available on
46 # the path
47 $openoffice_conversion_available = 1;
48 $no_openoffice_conversion_reason = "";
49
50 if (! defined $ENV{'GEXT_OPENOFFICE'}) {
51 $openoffice_conversion_available = 0;
52 $no_openoffice_conversion_reason = "gextopenofficenotinstalled";
53 }
54 else {
55 my $gextoo_home = $ENV{'GEXT_OPENOFFICE'};
56 my $jodjar = &util::filename_cat($gextoo_home,"lib","java","jodconverter.jar");
57
58 if (!-e $jodjar) {
59 #print STDERR "Failed to find $jodjar\n";
60 $openoffice_conversion_available = 0;
61 $no_openoffice_conversion_reason = "gextjodconverternotinstalled";
62 }
63 else {
64 # test to see if soffice is in path
65 my $cmd = "soffice -headless 2>&1"; # for linux and mac
66
67 if ($ENV{'GSDLOS'} =~ m/^windows$/) {
68 if(!defined $ENV{'SOFFICE_HOST'}) {
69 $ENV{'SOFFICE_HOST'} = "localhost";
70 }
71 if(!defined $ENV{'SOFFICE_PORT'}) {
72 $ENV{'SOFFICE_PORT'} = "8200";
73 }
74 if(!defined $ENV{'JODCONVERTER_PORT'}) {
75 $ENV{'JODCONVERTER_PORT'} = "8100";
76 }
77 # important to have this set when the Greenstone server
78 # and open office is on a remote windows machine
79 if(!defined $ENV{'SOFFICE_HOME'}) {
80 $ENV{'SOFFICE_HOME'} = &util::filename_cat($ENV{'ProgramFiles'},"OpenOffice.org 3");
81 }
82 my $ooffice_dir_guess =
83 &util::filename_cat($ENV{'SOFFICE_HOME'},"program");
84 if (-d $ooffice_dir_guess) {
85 &util::envvar_append("PATH",$ooffice_dir_guess);
86 }
87
88 # for windows, when working on a remote system, want to be able to start OO if
89 # not already running. We'll use the uno socket method to do so. Else client-gli
90 # tends to hang, waiting for the prompt to return after OO has been started up
91 # (which doesn't happen, so need to Ctrl-C GLI and run it again for it to work).
92 $cmd = "start \"soffice process\" soffice \"-accept=socket,host=$ENV{'SOFFICE_HOST'},port=$ENV{'SOFFICE_PORT'};urp;StarOffice.ServiceManager\" -headless 2>&1";
93 $cmd .= " >nul";
94 #print STDERR "***** Tried to start-up OpenOffice with:\n$cmd\n";
95 }
96 else {
97 # Windows seems to launch OpenOffice as a service (i.e.
98 # automatically puts it in the background).
99 # For Unix putting it in the background needs to be done
100 # explicitly
101
102 $cmd .= " >/dev/null &";
103 }
104
105 my $status = system($cmd);
106 if ($status != 0) {
107 #print STDERR "Failed to run: $cmd\n";
108 #print STDERR "$!\n";
109 $openoffice_conversion_available = 0;
110 $no_openoffice_conversion_reason = "openofficenotinstalled";
111 }
112 }
113 }
114}
115
116my $arguments = [
117 { 'name' => "openoffice_port",
118 'desc' => "{OpenOfficeConverter.openoffice_port}",
119 'type' => "int",
120 'deft' => "8100",
121 'range' => "81,",
122 'reqd' => "no" },
123 ];
124
125
126my $options = { 'name' => "OpenOfficeConverter",
127 'desc' => "{OpenOfficeConverter.desc}",
128 'abstract' => "yes",
129 'inherits' => "yes",
130 'args' => $arguments };
131
132sub new {
133 my ($class) = shift (@_);
134 my ($pluginlist,$inputargs,$hashArgOptLists,$auxilary) = @_;
135 push(@$pluginlist, $class);
136
137 push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
138 push(@{$hashArgOptLists->{"OptList"}},$options);
139
140 my $self = new BaseMediaConverter($pluginlist, $inputargs,
141 $hashArgOptLists, $auxilary);
142
143 if ($self->{'info_only'}) {
144 # don't worry about any options etc
145 return bless $self, $class;
146 }
147 if (!$openoffice_conversion_available) {
148 $self->{'no_openoffice_conversion_reason'} = $no_openoffice_conversion_reason;
149
150 my $outhandle = $self->{'outhandle'};
151 &gsprintf($outhandle, "OpenOfficeConverter: {OpenOfficeConverter.noconversionavailable} ({OpenOfficeConverter.$no_openoffice_conversion_reason})\n");
152 }
153
154 $self->{'openoffice_conversion_available'} = $openoffice_conversion_available;
155
156 return bless $self, $class;
157
158}
159
160sub init {
161 my $self = shift(@_);
162 my ($verbosity, $outhandle, $failhandle) = @_;
163
164 if ($openoffice_conversion_available) {
165 my $oo_port = $self->{'openoffice_port'};
166
167 my $launch_cmd = "soffice";
168 $launch_cmd .= " \"-accept=socket,host=localhost,port=$oo_port;urp;StarOffice.ServiceManager\"";
169 $launch_cmd .= " -headless";
170 $self->{'openoffice_launch_cmd'} = $launch_cmd;
171 }
172
173 $self->{'ootmp_file_paths'} = ();
174}
175
176sub deinit {
177 my $self = shift(@_);
178
179 $self->clean_up_temporary_files();
180}
181
182
183sub convert {
184 my $self = shift(@_);
185 my $source_file_full_path = shift(@_);
186 my $target_file_type = shift(@_);
187 my $convert_options = shift(@_) || "";
188 my $convert_id = shift(@_) || "";
189 my $cache_mode = shift(@_) || "";
190
191 return (0,undef,undef) unless $openoffice_conversion_available;
192 # check the filename
193 return (0,undef,undef) if ( !-f $source_file_full_path);
194
195 my $outhandle = $self->{'outhandle'};
196 my $verbosity = $self->{'verbosity'};
197
198 my $source_file_no_path = &File::Basename::basename($source_file_full_path);
199 # Determine the full name and path of the output file
200 my $target_file_path;
201 if ($self->{'enable_cache'}) {
202 $self->init_cache_for_file($source_file_full_path);
203 my $cache_dir = $self->{'cached_dir'};
204 my $file_root = $self->{'cached_file_root'};
205 $file_root .= "_$convert_id" if ($convert_id ne "");
206 my $target_file = "$file_root.$target_file_type";
207 $target_file_path = &util::filename_cat($cache_dir,$target_file);
208 }
209 else {
210 $target_file_path = &util::get_timestamped_tmp_filename_in_collection($source_file_full_path, $target_file_type);
211 push(@{$self->{'ootmp_file_paths'}}, $target_file_path);
212 }
213
214 # Generate and run the convert command
215
216 my $gextoo_home = $ENV{'GEXT_OPENOFFICE'};
217 my $jodjar = &util::filename_cat($gextoo_home,"lib","java","jodconverter.jar");
218
219 # debugging: print out all the env vars, when import's verbosity is high
220 #foreach my $key (sort(keys %ENV)) {
221 # print $outhandle "$key = $ENV{$key}\n";
222 #}
223
224# *If* SOFFICE_HOME\program was not added to the PATH, *another* way is to insert:
225# -Doffice.home=C:\\PROGRA~1\\OPENOF~1.ORG
226# into the command to launch jodconverter so that, when using the remote GS server
227# on Windows, jodconverter can find the openoffice installation:
228# my $office_short_path = Win32::GetShortPathName($ENV{'SOFFICE_HOME'});
229# my $convert_cmd = "java -Doffice.home=\"".$office_short_path."\" -jar \"$jodjar\"";
230
231 my $convert_cmd = "java -jar \"$jodjar\" --port $ENV{'JODCONVERTER_PORT'}";
232 $convert_cmd .= " \"$source_file_full_path\" \"$target_file_path\"";
233
234 if ($verbosity>2) {
235 print $outhandle "Convert command: $convert_cmd\n";
236 }
237
238 my $print_info = { 'message_prefix' => "OpenOffice Conversion",
239 'message' => "Converting $source_file_no_path to: $target_file_type" };
240 $print_info->{'cache_mode'} = $cache_mode if ($cache_mode ne "");
241
242 my ($regenerated,$result,$had_error)
243 = $self->autorun_general_cmd($convert_cmd,$source_file_full_path, $target_file_path,$print_info);
244 if ($had_error) {
245 return (0, $result,$target_file_path);
246 }
247 return (1, $result,$target_file_path);
248}
249
250
251sub convert_without_result {
252 my $self = shift(@_);
253
254 my $source_file_path = shift(@_);
255 my $target_file_type = shift(@_);
256 my $convert_options = shift(@_) || "";
257 my $convert_id = shift(@_) || "";
258
259 return $self->convert($source_file_path,$target_file_type,
260 $convert_options,$convert_id,"without_result");
261}
262
263
264sub tmp_area_convert_fileXX {
265 my $self = shift (@_);
266 my ($output_ext, $input_filename, $textref) = @_;
267
268 my $outhandle = $self->{'outhandle'};
269 my $convert_to = $self->{'convert_to'};
270 my $failhandle = $self->{'failhandle'};
271 my $convert_to_ext = $self->{'convert_to_ext'};
272
273 # derive tmp filename from input filename
274 my ($tailname, $dirname, $suffix)
275 = &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
276}
277
278
279sub clean_up_temporary_files {
280 my $self = shift(@_);
281
282 foreach my $ootmp_file_path (@{$self->{'ootmp_file_paths'}}) {
283 if (-e $ootmp_file_path) {
284 &util::rm($ootmp_file_path);
285 }
286 }
287
288 $self->{'ootmp_file_paths'} = ();
289}
290
291
292
2931;
Note: See TracBrowser for help on using the repository browser.