explota el potencial de openoffice con pyuno

Upload: aprender-libre

Post on 05-Apr-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Explota el Potencial de OpenOffice con PyUno

    1/5

    Esta es la gran cuestin no resuelta

    de la informtica pero, aunque no

    hayamos encontrado una solucin

    fiable, s se disponen de tcnicas que

    aumentan la probabilidad de que, al

    menos, se cree algn software til.

    Una de estas tcnicas consiste en

    emplear un sistema de componentes

    como base para el desarrollo. Un com-ponente es una cantidad de software

    que ofrece un servicio bien definido y

    que es reutilizable. Adems debe ser

    posible reutilizarlo de verdad: desde

    cualquier lenguaje y cualquier sitio.

    Cualquiera que tenga conocimiento

    sobre cmo funcionan los lenguajes de

    programacin a bajo nivel sabr que

    esto es muy muy complicado. Por ello

    se han desarrollado infraestructuras

    que nos permiten interactuar con los

    componentes de manera indirecta. A

    este software se le suele llamar mid-

    dleware (algo as como software deen medio).

    Ejemplos famosos de Middleware son

    J2EE, que muchos conocern, y

    CORBA, que a muchos les gustara no

    conocer. Ambos son sistemas enormes

    y costosos que relegan al programador

    a mera herramienta en manos de inge-

    nieros denominados arquitectos que

    conocen su compleja infraestructura.

    Pero los sistemas de componentes

    tambin se emplean en software libre y

    han dado buenos resultados. Quizs el

    ms desconocido es UNO, de Universal

    Network Objects, el sistema que

    emplea OpenOffice, ver Listado [1], y

    que SUN desarroll para su precursor:

    StarOffice.

    PyUNOUn sistema de componentes con el que

    slo se pueda programar en un

    lenguaje no tiene mucha utilidad. Poreso en OpenOffice se han asegurado de

    fomentar la creacin de interfaces a

    distintos lenguajes de programacin.

    Podemos acceder a UNO usando

    Javascript, Java, Ruby, Perl o Python

    (ver Recurso [2]).

    PyUNO es el nombre de la interfaz y

    podremos encontrarlo sin problemas en

    nuestra distribucin de Linux. Eviden-

    temente, necesitamos tambin tener

    instalado OpenOffice. En este artculo

    hemos realizado los programas usando

    OpenOffice 2.0, que cambi la interfaz

    respecto a la versin 1.0, y la versinde PyUNO 0.7.0.

    Un ejemplo rpidoVamos a crear el famoso Hola mundo

    con PyUNO. Para ello primero debemos

    arrancar OpenOffice con el siguiente

    comando desde el directorio donde est

    instalado:

    $> ./sofficeU

    "-accept=socket,U

    host=localhost,U

    port=2002;urp;"

    No es ni ser la ltima vez que

    desde esta seccin recordemos

    que la idea original de Stallman

    era la de que cada programa libre estu-

    viese construido sobre libreras de fun-

    ciones, de manera que su cdigo fuesereutilizable por cualquier otro pro-

    grama.

    Quizs en un programa pequeo no

    sea muy til este tipo de diseo, pero

    qu pasa con esos monstruos consumi-

    dores de memoria que rondan por nues-

    tros discos duros? Nos referimos a pro-

    gramas o entornos del calibre de

    Gnome, KDE, Mozilla u OpenOffice.

    Todo el mundo se queja de su tamao

    excesivo, su alto consumo de recursos y

    su inexplicable complejidad.

    Quizs con este artculo desmintamos

    este mito y hagamos que el lector mirecon nuevos ojos a estos maravillosos

    programas.

    Grandes sistemas decomponentesEl diseo de un gran programa puede

    llevar aos y cientos o miles de progra-

    madores. Organizar tal cantidad de per-

    sonas supone ya una locura slo por el

    hecho de asegurarse que todos cobren.

    Pero vayamos a nuestro mundillo

    cmo podemos organizarles para que

    el desarrollo no acabe en un fiasco?

    DESARROLLO Python

    50 Nmero 17 WWW.LINUX - M A G A Z I N E . E S

    PyUNO: Explota todo el potencial de OpenOffice

    PYTHON NO HAYMS QUE UNOHas visto alguna vez a los brokers de bolsa? Recuerdas sus sofisticados y caros pro-

    gramas para ver las cotizaciones de las empresas en bolsa en tiempo real? Nosotros

    haremos lo mismo con 70 lineas de cdigo Python, OpenOffice y la tecnologa UNO de

    OpenOffice. POR JOS MARA RUIZ

    050-053 Python xx 05.04.2006 16:29 Uhr Pgina 50

  • 7/31/2019 Explota el Potencial de OpenOffice con PyUno

    2/5

    Al arrancar OpenOffice se arranca su

    sistema de componentes. Podemos pen-

    sar en este proceso como en el arranque

    de un servidor, slo cuando est funcio-

    nando podrn los clientes trabajar con

    l.

    Las opciones que pasamos son para

    que se cree un socket y se escuche en

    localhost en el puerto 2002. Por defecto

    OpenOffice no abre el socket, de ma-

    nera que no podrn controlar nuestro

    OpenOffice sin nuestro consentimiento.

    OpenOffice incorpora de serie varios

    intrpretes de lenguajes, entre ellos unode Python que ya viene preconfigurado

    para poder hacer uso de la librera UNO.

    Est junto al resto de ejecutables de

    OpenOffice, as que lo ejecutaremos

    desde all. El programa que usaremos se

    encuentra en el Listado [2].

    El proceso es el siguiente:

    Obtenemos un contexto local (un

    sitio donde guardar los datos de la

    conexin)

    Arrancamos el componente UnoUrl-

    Resolver que nos sirve para acceder

    a otro OpenOffice en otro equipo

    (en nuestro caso accederemos anuestro propio equipo)

    Emplearemos el objeto resolverpara

    acceder al OpenOffice remoto

    Arrancamos un Desktop (escrito-

    rio) de OpenOffice (esto es una

    instancia de OpenOffice vaca)

    Arrancamos un SWriter (es decir, el

    procesador de textos) en el escrito-

    rio

    Obtenemos un cursor, con el que

    podremos posicionarnos dentro del

    texto

    e insertamos texto en el cursor

    El resultado, no muy espectacular,

    podemos verlo en la Figura [1]. Ya te-

    nemos nuestro hola mundo insertado

    en SWriter.

    Demasiado cdigo? Piensa por un

    momento lo que estamos haciendo.

    Hemos levantado dos componentes y

    hecho acceso remoto a otro OpenOffice.

    Este segundo OpenOffice puede estar en

    una mquina al otro lado del mundo. Es

    algo bastante impresionante, pero por el

    momento poco til. Veamos un poco

    ms sobre UNO antes de realizar un

    programa ms til.

    Arquitectura de UNOOpenOffice est implementado en

    C++. UNO se usa internamente para

    realizar cualquier cosa. Bsicamente

    OpenOffice no es ms que una gran

    cantidad de componentes que interac-

    tan entre s. Todo dentro de OpenOf-

    fice es un componente, as que

    podemos acceder a cualquier parte de la

    aplicacin, incluso reconstruir Open-

    Office en Python!

    Los sistemas de componentes usan

    un registro de componentes al que se lepuede pedir que arranque compo-

    nentes. El registro localiza el compo-

    nente en disco y lo carga en memoria,

    de manera que puede ser usado. Las lla-

    madas a las funciones no se realizan

    directamente, sino que se suele emplear

    algn sistema no dependiente de

    lenguaje o plataforma, como puede ser

    XML o un formato ASCII.

    El registro tambin debe ser capaz de

    gestionar los recursos que consume el

    componente, descargndolo de memo-

    ria cuando ya no sea necesario.

    Los componentes pueden ser progra-

    mados en cualquier lenguaje con el

    que se tenga interfaz. Un componente

    es un conjunto de ficheros que propor-

    cionan un servicio. Se acompaan deun fichero XML que describe su fun-

    cionalidad. Lo mejor es que podemos

    vincular ese servicio a algn compo-

    nente grfico, como por ejemplo un

    botn o men.

    Comenzaremos por realizar un pro-

    grama que funcionar de manera

    externa a OpenOffice y despus creare-

    mos un componente con l y lo inte-

    graremos en OpenOffice.

    Nuestro programa deStocksComencemos con la parte til, ver Lis-

    tado [2]. Vamos a crear un sistema que

    nos permita controlar las acciones de

    una serie de empresas que estn en

    bolsa dentro de un ndice tecnolgico,

    el Nasdaq (para algo estamos en una

    revista de informtica), usando la hoja

    de clculo SCalc y un programa

    Python. Nuestro programa acceder

    usando Internet a un sitio web donde

    podr recoger los datos en CSV (Val-

    ores Separados por Comas), los proce-

    sar y los introducir en SCalc.

    Comenzaremos por crear una fun-cin que recoja el fichero CSV y lo pro-

    cese. Lo que hacemos es conectarnos

    con la pgina web finance.yahoo.com .

    Yahoo tiene un sitio web bastante

    avanzado sobre cotizaciones de bolsa,

    y uno de sus servicios nos permite

    recoger los datos de cotizacin de una

    empresa en tiempo real en formato

    CSV. Sin embargo, Yahoo no nos per-

    mitir acceder a los datos demasiado a

    menudo, ya que dispone de un servi-

    cio de pago para ello, as que puede

    cortarnos el grifo en cualquier

    momento si hacemos demasiadas con-sultas por minuto. Por eso recogere-

    mos los datos cada 10 segundos. La

    funcin getSimbolo() se encargar de

    ello.

    Ahora ya tenemos los datos, te-

    nemos que mandarlos a SCalc. Hemos

    creado un objeto llamado Calc para

    gestionar el acceso. Hemos metido en

    el mtodo constructor (__init__) el

    cdigo que conecta con el OpenOffice,

    puesto que slo lo haremos una vez.

    Una hoja de clculo posee varias

    hojas, as que tendremos que solici-

    Python DESARROLLO

    51Nmero 17WWW.LINUX- M A G A Z I N E . E S

    01 import uno0203 localContext =

    uno.getComponentContext()0405 resolver =

    localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver",

    06localContext )

    07 ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )

    0809 desktop =

    ctx.ServiceManager.createInstanceWithContext(

    "com.sun.star.frame.Desktop",ctx)1011 doc =

    desktop.loadComponentFromURL("private:factory/swriter","_blank",0,())

    1213 cursor =

    doc.Text.createTextCursor()1415 doc.Text.insertString( cursor,

    "Hola Mundo", 0 )1617 ctx.ServiceManager

    Listado 1: programa Hola Mundo

    050-053 Python xx 05.04.2006 16:29 Uhr Pgina 51

  • 7/31/2019 Explota el Potencial de OpenOffice con PyUno

    3/5

    primera hoja, que es la que se ve

    cuando arrancamos SCalc.

    El mtodo actualiza() admite una

    lista con los datos de cotizacin y

    nmero que representa la fila donde

    aparecer en SCalc. Una hoja de clculo

    se compone de celdas y stas tienen un

    tipo. La funcin getCellByPosition() nos

    permite acceder a una celda pasndole

    la columna y la fila (al revs de lo nor-

    mal, as que cuidado).

    Una vez localizada la celda tenemos

    varias funciones para poder asignar un

    valor:

    setString(): para poner una cadena setValue(): para poner un nmero

    setFormula(): para poner una fr-

    mula

    El dato cotizacin es la lista de

    parmetro de cotizacin, pero vienen

    dados como cadenas de caracteres. Las

    posiciones 0, 2 y 3 son realmente cade-

    nas, pero el resto son nmeros. Por eso

    tenemos que convertir ciertos valores

    al tipo float() mediante la funcin

    float().

    El resultado se puede ver en la Figura

    [2], veremos cmo se abre una ventana

    tar una usando el mtodo getSheets(),

    que nos devuelve una lista con las dis-

    tintas hojas. Dentro de esta lista usare-

    mos getByIndex() para seleccionar la

    DESARROLLO Python

    52 Nmero 17 WWW.LINUX - M A G A Z I N E . E S

    01 import uno

    02 import random

    03 import time04 import httplib

    05 import csv

    06

    07 class Calc:

    08 def __init__(self):

    09 self.conecta()

    10

    11 def conecta (self):

    12 self.local =

    uno.getComponentContext()

    13 self.resolver =

    self.local.ServiceManager.crea

    teInstanceWithContext("com.sun

    .star.bridge.UnoUrlResolver",

    self.local)

    14

    15 self.context =

    self.resolver.resolve("uno:soc

    ket,host=localhost,port=2002;u

    rp;StarOffice.ComponentContext

    ")

    16

    17 self.desktop =

    self.context.ServiceManager.cr

    eateInstanceWithContext("com.s

    un.star.frame.Desktop",

    18self.context)

    19

    20 #self.doc =

    self.desktop.getCurrentCompone

    nt()21 self.doc =

    self.desktop.loadComponentFrom

    URL("private:factory/scalc","_

    blank",0,())

    22

    23 self.hojas =

    self.doc.getSheets()

    24 self.s1 =

    self.hojas.getByIndex(0)

    25

    26 def actualiza(self,

    cotizacion, fila):

    27

    28 i = 0

    29 for entrada in

    cotizacion:

    30 if (i == 0) or (i

    == 2) or (i ==3):

    31

    self.s1.getCellByPosition(i,fi

    la).setString(entrada)

    32 else:

    33

    self.s1.getCellByPosition(i,fi

    la).setValue(float(entrada))

    34

    35 i = i + 136

    37 def getSimbolo(simbolo):

    38 c =

    httplib.HTTPConnection("finance.yahoo.com")

    39

    c.request("GET","/d/quotes.csv

    ?s="+simbolo+"&f=sl1d1t1c1ohgv

    &e=.csv")

    40 r = c.getresponse()

    41 cad = r.read()

    42 reader = csv.reader([cad])

    43 resultado = []

    44 for row in reader:

    45 resultado = row

    46 return resultado

    47

    48 if __name__ == '__main__':

    49

    50 simbolos =

    ["GOOG","MSFT","RHAT"]

    51

    52 c = Calc()

    53

    54 while(1):

    55 i = 0;

    56 for s in simbolos:

    57

    c.actualiza(getSimbolo(s),i)

    58 i = i + 1

    5960 time.sleep(10)

    Listado 2: OfficeBroker

    Figura 1: Un documento de Write de OpenOffice con el ineludible Hello World generado a par-

    tir de PyUNO.

    050-053 Python xx 05.04.2006 16:29 Uhr Pgina 52

  • 7/31/2019 Explota el Potencial de OpenOffice con PyUno

    4/5

    de SCalc y se rellena con los valores de

    las contizaciones, adems de cmo se

    actualizan cada 10 segundos. Si

    creamos un grfico que use esos va-

    lores se actualizar con ellos.

    Pero este es un programa externo

    estara bien que pudisemos hacer eso

    pulsando un botn

    Creamos un componenteUNOLos componentes UNO no son ms que

    cdigo debidamente empaquetado. Los

    paquetes que OpenOffice admite tienen

    una estructura fija. Son ficheros ZIP

    que contienen los ficheros con el

    cdigo fuente, recursos (como im-

    genes) y un fichero de configuracin

    XML.

    Los ficheros deben tener nombres

    especiales. El fichero de configuracin

    debe llamarse Addons.xcu y permite

    asignar el cdigo fuente del paquete con

    el widget que deseemos, un botn, una

    entrada de un men Ver Listado [3].

    La sintaxis del fichero parece bastante

    complicada, cuando en realidad no esmuy difcil de entender. Bsicamente

    decimos que queremos que nuestro com-

    ponente se asocie con una entrada en el

    men Addons que est en Tools o Her-

    ramientas en castellano. Nuestro compo-

    nente tiene una ruta que especificaremos

    despus y que es:

    org.openoffice.comp.pyuno.U

    linuxmagazine.Stock

    Esta ruta la hemos creado nosotros y

    tenemos que tener cuidado de que sea

    nica, por eso hemos incorporado li-

    nuxmagazine en ella ;). Definimos un

    ttulo, que puede estar en varios

    idiomas, y una imagen, que hemos

    escogido de entre las que proporcionaOpenOffice.

    El fichero con el cdigo fuente Python en

    s se puede ver en el Listado 4. Tenemos un

    objeto llamado StockJob que ser el que se

    invocar en caso de pulsar la entrada en el

    men. Ese objeto se vincula a la ruta que

    vimos antes. Cada vez que se pulse sobre la

    entrada del men se ejecutar el mtodo

    trigger, que descargar de Internet las coti-

    zaciones y las mostrar en la hoja de cl-

    culo. Es posible hacer que slo se muestre

    el men cuando arrancamos la hoja de cl-

    culo SCalc, pero por motivos de espacio no

    hemos puesto la restriccin. An as si noestamos en una hoja de clculo no suce-

    der nada, simplemente no funcionar.

    Manejo de paquetes enOpenOfficeAhora tenemos que generar nuestro

    paquete UNO. Para ello necesitaremos el

    programa ZIP, gzip no nos vale, y crear un

    fichero:

    $> zip stock.zipU

    stock_comp.py Addons.xcu

    updating: ...../Addons.xcuU

    Python DESARROLLO

    53Nmero 17WWW.LINUX- M A G A Z I N E . E S

    01

    02

    05

    06

    07

    08

    09

    10

    service:org.openoffice.

    comp.pyuno.linuxmagazine.Stock

    ?insert

    11

    12

    13

    14 Stock

    Market

    15 Cotizacin enBolsa

    16

    17 18

    _self

    19

    20

    21

    private:image/3216

    22

    23

    24

    25

    26

    27

    Listado 3: Addons.xcu

    Figura 2: Nuestro programa examina los valores de la bolsa NASDAQ disponibles en Yahoo a

    intervalos regulares y los inserta en una hoja de clculo de OpenOffice.

    050-053 Python xx 05.04.2006 16:29 Uhr Pgina 53

  • 7/31/2019 Explota el Potencial de OpenOffice con PyUno

    5/5

    Con esto concluye la instalacin del

    paqueteno ha sido tan difcil!

    Cuando arranquemos de nuevo

    OpenOffice podremos seleccionar la

    hoja de clculo SCalc y en el men

    Tools/Herramientas veremos cmo ha

    aparecido al final un nuevo submen:

    Complementos (add-ons). Dentro

    del mismo aparecer una nueva

    entrada llamada Cotizacin de

    Bolsa. Si lo pulsamos aparecen los

    datos de 3 compaas (Google,

    Microsoft y Redhat) del Nasdaq ennuestra hoja de clculo.

    ConclusinPython nos permite

    un uso nuevo de

    algo tan trillado

    como puede

    ser un

    paquete

    ofimtico.

    OpenOffice

    entero es

    accesible

    desde Python; no es difcil imaginarse

    programas que podran facilitarnos

    mucho la vida y no son tan difciles de

    crear gracias a PyUNO. No hemos

    explorado la posibilidad de actuar

    sobre un OpenOffice remoto por falta

    de espacio, pero es una nueva posibili-

    dad que abre un camino para aplica-

    ciones muy interesantes, como puede

    ser la edicin distribuida de documen-

    tos o un uso ms creativo de la hoja de

    clculo.

    Todo un mundo de posibilidades seabre ante nosotros gracias a Python. I

    (deflated 59%)

    updating: ...../stock_comp.pyU

    (deflated 57%)

    >

    Este fichero debe ser integrado en Open-

    Office, iremos al directorio donde est

    instalado y ejecutaremos como root:

    $> sudo ./unopkg addU

    stock.zip

    >

    DESARROLLO Python

    [1] El sitio de OpenOffice: http://www.

    openoffice.org

    [2] El puente entre Python y OpenOf-

    fice: http://udk.openoffice.org/python/

    python-bridge.html

    [3] Los listados de este arculo: http://

    www.linux-magazine.es/Magazine/

    Downloads/17

    RECURSOS

    Listado 4: stock_comp.py

    01 import uno

    02 import unohelper

    0304 import random

    05 import time

    06 import httplib

    07 import csv

    08

    09 from com.sun.star.task import

    XJobExecutor

    10

    11 def getSimbolo(simbolo):

    12 c =

    httplib.HTTPConnection("financ

    e.yahoo.com")

    13

    c.request("GET","/d/quotes.csv?s="+simbolo+"&f=sl1d1t1c1ohgv

    &e=.csv")

    14 r = c.getresponse()

    15 cad = r.read()

    16 reader = csv.reader([cad])

    17 resultado = []

    18 for row in reader:

    19 resultado = row

    20 return resultado

    21

    22 class StockJob(

    unohelper.Base, XJobExecutor

    ):

    23 def __init__( self, ctx ):

    24

    25 self.ctx = ctx26

    27 def trigger( self, args ):

    28 desktop =

    self.ctx.ServiceManager.create

    InstanceWithContext(

    29

    "com.sun.star.frame.Desktop",

    self.ctx )

    30

    31 model =

    desktop.getCurrentComponent()

    32

    33 self.hojas =

    model.getSheets()34

    35 self.s1 =

    self.hojas.getByIndex(0)

    36

    37 simbolos =

    ["GOOG","MSFT","RHAT"]

    38 i = 0;

    39

    40 for s in simbolos:

    41

    self.actualiza(getSimbolo(s),i

    )

    42 i = i + 1

    43

    44 def actualiza(self,

    cotizacion, fila):45 i = 0

    46 for entrada in

    cotizacion:

    47 if (i == 0) or (i

    == 2) or (i ==3):

    48

    self.s1.getCellByPosition(i,fi

    la).setString(entrada)

    49 else:

    50

    self.s1.getCellByPosition(i,fi

    la).setValue(float(entrada))

    51

    52 i = i + 153

    54 g_ImplementationHelper =

    unohelper.ImplementationHelper

    ()

    55

    56

    g_ImplementationHelper.addImpl

    ementation( StockJob,

    57

    "org.openoffice.comp.pyuno.lin

    uxmagazine.Stock",

    58

    ("com.sun.star.task.Job",),)

    54 Nmero 17 WWW.LINUX - M A G A Z I N E . E S

    050-053 Python xx 05.04.2006 16:29 Uhr Pgina 54