2007.08_OpenOffice–narzędzie do konwersji_[Open Office].pdf

(681 KB) Pobierz
332796225 UNPDF
rozwiązania
Demon konwersji
– narzędzie do konwersji
Bartłomiej Górny
Główny zamysł programu oood (skrót od OpenOfice.org Daemon ) to udostępnienie programom klienckim
olbrzymich możliwości OpenOfice'a w zakresie konwersji i edycji plików w różnych formatach poprzez prosty
w użyciu i stabilny interfejs. Oood potrai dokonywać konwersji dokumentów pomiędzy wszystkimi formatami
obsługiwanymi przez OpenOfice'a – najczęściej potrzebna jest konwersja między formatami MSOfice a ODF,
ale oood może także generować pdf-y, zamienić dokument tekstowy na docbook, arkusz kalkulacyjny
na csv, a prezentację na zestaw stron www albo animację we Flashu. Jest w stanie także odczytać zapisane
w dokumencie metadane, a także te metadane w dokumencie zmienić.
P rogram powstał pierwotnie na potrzeby systemu
jedno po drugim. W przypadku wystąpienia problemów
z otwarciem nadesłanego pliku lub ogólnych problemów
z funkcjonowaniem serwera informuje on klientów o wy-
stąpieniu takiej sytuacji i podejmuje działania naprawcze,
nie przerywając przy tym obsługi nadchodzących żądań.
Do komunikacji z klientami oood wykorzystuje spe-
cjalny protokół, nieco podobny do protokołu HTTP – każ-
da odpowiedź wysłana klientowi składa się z kodu, komu-
nikatu i danych żądanych przez klienta.
Taka architektura zapewnia stabilność systemu – te-
sty wykazały, że oood uruchomiony na zwykłym lapto-
pie jest w stanie obsłużyć 100 żądań konwersji pliku wy-
słanych jednocześnie – wszystkie żądania zostały prawi-
dłowo obsłużone. W ramach innego testu oood pracując
bez przerwy przez trzy i pół dnia, skonwertował 100 000
plików.
Architektura
Oood jest w zasadzie serwerem XMLRPC napisanym w ję-
zyku Python na bazie standardowego modułu Simple-
XMLRPCServer. Aplikacje klienckie napisane w Pythonie
mogą skorzystać z dostarczanej przez oood biblioteki
oood_common i standardowego modułu xmlrpclib . Rzecz ja-
sna – korzystać z usług serwera mogą także aplikacje napi-
sane w dowolnym innym języku. Serwer oood uruchamia
jedną instancję OpenOfice'a, z którą następnie komunikuje
się poprzez gniazdo ( socket ). Instancja ta korzysta ze swoje-
go katalogu domowego, ma więc swoją własną konigura-
cję. Instancja jest kontrolowana przez serwer, który w razie
potrzeby może ją zrestartować.
Serwer działa wielowątkowo, jest więc w stanie przy-
jąć jednocześnie wiele żądań, skolejkować je i obsłużyć
Instalacja i uruchomienie
Program można pobrać z publicznego repozytorium svn
(pakiety RPM są w przygotowaniu). Do poprawnego
działania wymaga Pythona 2.4 i OpenOfice'a 2.0 bądź
2.1 lub Pythona 2.5 i OpenOfice'a 2.2. Opcje konigura-
36
sierpień 2007
OpenOfice
zarządzania dokumentami ERP5-DMS, ale je-
go możliwe zastosowania są znacznie szersze.
Oood jest rozpowszechniany na licencji GPL,
a jego kod źródłowy jest dostępny w publicznym repozy-
torium systemu ERP5.
332796225.014.png 332796225.015.png 332796225.016.png 332796225.017.png
 
rozwiązania
Demon konwersji
Listing 1. Python
Listing 2. Java
sp=xmlrpclib.ServerProxy('http:
//localhost:8008')
data = open ( 'doc/test.doc' ) . read ()
encdata = base64 . encodestring ( data )
response = sp . generate ( { 'data' :
encdata , 'extension' : 'pdf' } )
if response [ 0 ] == 200 :
decdata = base64 . decodestring ( respo
nse [ 1 ][ 'data' ])
open ( 'test.pdf' ,
'w' ) . write ( decdata )
else :
print 'nie udalo sie: ' ,
response [ 2 ]
import java.util.*; import org.apache.xmlrpc.client.*;
import org.apache.ws.commons.util.*; import java.net.URL;
byte [] inData = // zawartość pliku wejściowego
String encData = Base64 . encode ( inData ) ;
XmlRpcClientConigImpl conig = new XmlRpcClientConigImpl () ;
conig . setServerURL ( new URL ( server_url )) ;
XmlRpcClient client = new XmlRpcClient () ;
client . setConig ( conig ) ;
HashMap params = new HashMap () ; params . put ( "extension" , "pdf" ) ;
params . put ( "data" , encData ) ; Vector paramVector = new Vector ( 1 ) ;
paramVector . add ( params ) ;
Object [] result = ( Object []) client . execute ( "generate" , paramVector ) ;
int resultCode = (( Integer ) result [ 0 ]) . intValue () ;
if ( resultCode == 200 ){
encData = ( String )(( Map ) result [ 1 ]) . get ( "data" ) ;
byte [] outData = Base64 . decode ( encData ) ;
// outData zawiera przekonwertowany plik
} else {
System . out . println ( "nie udalo sie " + ( String ) result [ 2 ]) ;
}
cyjne znajdują się w pliku oood.conf . Kon-
iguracja programu jest dość prosta, wystar-
czy ustawić ścieżkę do programu i do miej-
sca, gdzie znajdują się pliki wykonywalne
OpenOfice'a, port, na którym ma nasłuchi-
wać oood i nazwę lokalnej drukarki. Oczy-
wiście użytkownik, który będzie uruchamiał
oood, musi mieć prawo do zapisu do po-
danych ścieżek. Przy starcie oood Open-
Ofice zostanie uruchomiony w tle, natomiast
za pierwszym razem należy uruchomić in-
stancję OpenOfice „na wierzchu” poleceniem:
./start.py –top.
Następnie przejść przez procedurę reje-
stracji, a potem w uruchomionym już Open-
Ofice'ie ustawić ścieżkę do miejsca, gdzie za-
instalowany jest Java Runtime Environment. To
ostatnie znakomicie przyspiesza uruchamia-
nie OpenOfice'a, można więc śmiało zmniej-
szyć zmienną instance_load_time do 10 sekund,
oood będzie działał znacznie prędzej.
Samego demona uruchamia się polece-
niem: ./runserw.py –start.
Kiedy już zacznie działać, można podglądać,
co dzieje się w środku poleceniami: ./start.
py –status i ./start.py –threads.
Listing 3. PHP
include 'xmlrpc.inc' ; // https://sourceforge.net/projects/phpxmlrpc/
function getDataItem ( $response , $item ){
return $response [ 'data' ] - > structMem ( $item ) - > scalarval () ;
}
function analyzeResponse ( $res ){
$val = $res - > value () ;
$list = $val - > scalarval () ;
$status_code = $list [ 0 ] - > scalarval () ;
$data = $list [ 1 ] ;
$msg = $list [ 2 ] - > scalarval () ;
return array ( 'code' = > $status_code , 'data' = > $data , 'message' = > $msg ) ;
}
function makeRequest ( $method , $params ){
$newparams = array () ;
foreach ( $params as $k = > $v ){
if ( $k == 'data' ){ $v = base64_encode ( $v ) ;
}
$newparams [ $k ] = new xmlrpcval ( $v , 'string' ) ;
}
$newparams = new xmlrpcval ( $newparams , 'struct' ) ;
return new xmlrpcmsg ( $method , array ( $newparams )) ;
}
$iledata = // dane wejsciowe
$params = array ( 'data' = > $iledata , 'extension' = > 'pdf' ) ;
$msg = makeRequest ( 'generate' , $params ) ;
$client = new xmlrpc_client ( 'http://192.168.20.192:8008' ) ;
$res = $client - > send ( $msg ) ;
$response = analyzeResponse ( $res ) ;
if ( $response [ 'code' ] == 200 ){
$data = getDataItem ( $response , 'data' ) ; // zawartosc pliku po skonwertowaniu
} else {
echo 'Failed with code ' . $response [ 'code' ] . ', message
"' . $response [ 'message' ] ;
}
Sposób użycia
Oood nie ma interfejsu użytkownika – jest
przeznaczony wyłącznie do użytku przez ap-
likacje klienckie. Mogą one korzystać z pu-
blicznych metod serwera. Jako argument
funkcji klient powinien przekazać słownik
zawierający odpowiednie parametry oraz
dane zakodowane przez base64. Rezultatem
wywołania zdalnej metody jest lista zawie-
rająca trzy elementy:
• kod (status)
• słownik z danymi zwróconymi przez
serwer
• komunikat odpowiadający statusowi.
www.lpmagazine.org
37
332796225.001.png 332796225.002.png 332796225.003.png 332796225.004.png 332796225.005.png 332796225.006.png
 
rozwiązania
Demon konwersji
Listing 4. C++
Kody protokołu oood
200: 'OK',
401: 'requested method is not provided',
402: 'the document could not be processed',
403: 'timeout while processing document',
404: 'malformed request',
501: 'the server is restarting',
502: 'pool is empty, the server will be restarted',
503: 'the server is out of sync and will
be restarted',
504: 'unknown error'
# include "XmlRpc.h" // xmlrpc++ library ver.0.7 -
http://xmlrpcpp.sourceforge.net/
# include "Base64.h" // Base64 class from C++ Sockets Library -
http://www.alhem.net/Sockets/index.html
#include <iostream>
using namespace XmlRpc ;
using namespace std ;
int main ( int argc , char * argv []) {
FILE * inile = fopen ( "test2.odt" , "r" );
std :: string data ;
Base64 tmp_base ;
tmp_base . encode ( inile , data , false );
XmlRpcClient client ( "localhost" , 8008 );
XmlRpcValue result ;
XmlRpcValue Args ;
Args [ "data" ] = data . c_str ();
Args [ "extension" ] = "pdf" ;
client . execute ( "generate" , Args , result );
std :: cout << "Oood result code: " << result [ 0 ] << std :: endl ;
std :: string dec_data ;
tmp_base . decode ( result [ 1 ][ "data" ] , dec_data );
FILE * outile = fopen ( "test.pdf" , "wb" );
const char * outbuf = dec_data . c_str ();
fwrite ( outbuf , sizeof ( dec_data [ 0 ]) , dec_data . size ()- 1 , outile );
fclose ( outile );
return 0 ;
}
lista formatów, na które
może być skonwertowany
dany dokument; parame-
trem może być typ dokumentu
( text , spreadsheet ),
rozszerzenie
( doc , txt ) lub mimetype
(np application/msword )
generate konwersja dokumentu
na wybrany format
getmetadata pobranie metadanych
dokumentu
setmetadata edycja metadanych dokumentu
printDocument wydruk dokumentu na lokalnej
drukarce serwera
Poniżej zamieszczone są przykładowe kody
klienta oood w różnych językach programo-
wania; są to tylko najważniejsze fragmenty
kodu – kompletne przykłady można znaleźć
w repozytorium svn .
• generowanie raportów w systemie ERP5
– system ERP5 ma wbudowaną możli-
wość generowania raportów w forma-
tach ODF na podstawie szablonów xml-
owych; dzięki współpracy z oood rapor-
ty mogą być na żądanie użytkownika
generowane także w formacie MS Ofi-
ce, html czy pdf .
• system zarządzania dokumentami –
w systemie ERP5-DMS każdy dokument
w jakimkolwiek formacie „biurowym”
jest natychmiast po jego umieszczeniu
w systemie konwertowany przez oood
na trzy formaty:
plain text – co umożliwia jego indek-
sowanie przez systemową wyszuki-
warkę,
html – dzięki czemu możliwy jest pod-
gląd treści dokumentu w przeglądarce
bez konieczności jego pobierania,
ODF – w tym formacie dokument
jest składowany w systemie.
Użytkownik, który chce pobrać doku-
ment z systemu może wybrać format, ja-
ki mu najbardziej odpowiada – ODF, MS
czy jakikolwiek inny (obecnie oood ob-
sługuje 111 formatów).
mail2print – jest to dedykowany serwer
pocztowy, który każdy odebrany e-mail
otwiera i samoczynnie drukuje wszyst-
kie załączone do maila dokumenty,
wykorzystując do tego celu możliwości
oood. Powstał na potrzeby irmy otrzy-
mującej drogą mailową znaczne ilości
zamówień, które muszą być wydruko-
wane.
Python
Przykładowy skrypt klienta w Pythonie mo-
że wyglądać następująco: import xmlrpclib,
base64. Ułatwieniem jest moduł oood_com-
mon zawierający klasy Request i Response ,
które m. in. sprawdzają poprawność argu-
mentów i kodują/dekodują dane. Oto ten sam
skrypt wykorzystujący moduł oood_common .
W przygotowaniu
– „multi-oood”
Niedługo powinien ujrzeć światło dzienne
„multi-oood” – serwer pośredniczący, któ-
ry umożliwi jednoczesne korzystanie z wielu
uruchomionych jednocześnie instancji oood.
Znacznie usprawni to jego działanie w przy-
padku korzystania z oood przez wielu użyt-
kowników jednocześnie.
Zastosowania
Oood doczekał się już paru praktycznych za-
stosowań również w środowiskach produk-
cyjnych:
W Sieci
O autorze
• Strona domowa oood:
http://wiki.erp5.org/
HowToUseOood
• Repozytorium svn:
http://svn.erp5.org/repos/
public/erp5/trunk/utils/oood
• Lista dyskusyjna:
erp5-dev@erp5.org
Bartłomiej Górny jest prezesem i udzia-
łowcem ERP5 Polska sp. z o.o. - irmy zaj-
mującej się rozwojem i wdrażaniem aplika-
cji na bazie systemu ERP5 (platformy biz-
nesowej dostępnej na licencji GPL).
Kontakt z autorem: bartek@erp5.pl
38
sierpień 2007
getAllowed-
TargetItemList
332796225.007.png 332796225.008.png 332796225.009.png 332796225.010.png 332796225.011.png 332796225.012.png 332796225.013.png
 
Zgłoś jeśli naruszono regulamin