miércoles, 17 de octubre de 2007

Firewatir revisited (y lo que te rondaré morena)

Algunos detalles interesantes sobre el uso de Firewatir:
  • Con la última versión de la gema y de la extensión de Firefox no es necesario arrancar éste con firefox.exe -jssh.
  • No he conseguido que funcione en oculto. Watir es, en general, mucho más rápido en modo oculto y pensé que Firewatir también lo sería. Por tanto, hasta ahora su ejecución me resulta lenta. Lo que sí se puede hacer es minimizar la ventana de Firefox.
  • Con la última versión de la gema podemos saltar los alert y confirm del navegador de manera sencilla:

    my_firefox.startClicker('OK', 10, nil, nil)
    my_firefox.button(:value, "Acepto").click()


    donde el primer parámetro es el botón del messagebox que queremos pinchar ('OK' o 'Cancel'). En versiones anteriores, se hacía de esta otra manera:

    my_firefox.button(:value, "Acepto").click_no_wait
    my_firefox.click_jspopup_button('OK')
    my_firefox.wait()

  • En mi opinión, la gestión de ventanas no está muy conseguida. En la última versión cada

    my_firefox = Firefox.start('http://danimataonrails')

    abre una ventana nueva, lo cual clarifica un bastante el manejo de ventanas y hace recomendable un

    my_firefox.close()

    al terminar el crawling.

Seguiremos informando.

martes, 16 de octubre de 2007

A tiro hecho (I)

La mitad de las veces que busco en google información sobre ruby busco las mismas cosas, las que soy incapaz de memorizar dado mi estado neuronal. Una de ellas es ésta: el formateo de Time, Date y DateTime.

Los que más uso, extaído del link...

%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%S - Second of the minute (00..60)
%w - Day of the week (Sunday is 0, 0..6)
%y - Year without a century (00..99)
%Y - Year with century

Por cierto, te has apuntado ya a la conferencia Rails de Madrid?

domingo, 14 de octubre de 2007

Firewatir sobre Windows

Después de darme de cabezazos contra un servidor y no poder terminar un crawler ni con rest-open-uri ni con mechanize, he terminado por programarlo sobre firewatir.

El punto de mayor información sobre fire watir es éste.

Y después de instalar la extensión de Firefox, instalar la gema FireWatir, lo y arrancar firefox con firefox.exe -jssh el código es muy sencillo:

require 'firewatir'
include FireWatir

#me hago con un navegador
my_firefox = Firefox.new
#voy a la página que me interesa
my_firefox.goto('http://www.danimata.com')
#relleno un combo
my_firefox.select_list(:name, 'Genre').select_value('man')
#relleno un campo de texto
my_firefox.text_field(:name, 'FirstName').set('Daniel')
#pincho el botón que submite la página
my_firefox.button(:value, "Continue").click


Así de fácil es y así se lo hemos contado. Como siempre, salud¡

jueves, 4 de octubre de 2007

SOAP hasta en la SOPA

Madre del amor¡

Llevo tres días intentando desentrañar cómo acceder a un Web Service que no tiene descubrimiento por wsdl. Lo único que tenía era unos xsd medio decentes (y digo medio decentes porque xsd2ruby cascaba al ejecutarlo contra ellos) y unos fuentes java que se supone que funcionan. Además, el acceso se realiza sin SOAP action.

Después de intentar emular al script wsdl2ruby y generar los objetos y métodos que él genera con estas manitas y mi tricotosa he tenido que generar un mensaje con su SOAPHeader y su SOAPBody y enviarlo por el método invoke de SOAP::RPC::Driver. Entre todas las pruebas que he tenido que hacer destaco estas tres:

  • después de observar un mensaje recibido como error del servidor de destino, vi que su SOAPBody contenía objetos SOAPStruct e intenté emularlo para crear la estructura XML que el servidor entiende.
  • tuve que cambiar todos los SOAPStruct por SOAPElement porque el servidor aplicaba sus xsd al contenido recibido y los nodos enviados llevaban el atributo encodingstyle, no aceptado en el formato esperado.
  • cada SOAPElement se puede tratar como Hash y cada SOAPStruct como Hash y como Array.
Unas líneas de código como muestra...

driver = SOAP::RPC::Driver.new("http://localhost:8003", "http://my.namespaces")

sh = SOAP::SOAPHeader.new
sb = SOAP::SOAPBody.new
sb.add('Message', SOAP::SOAPElement.new('Message'))
sb[0].extraattr['xmlns'] = 'http://my.namespaces'
sb[0].extraattr['xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'
sb[0].extraattr['xsi:schemaLocation'] = 'http://my.schemas'
sb[0].add(SOAP::SOAPElement.new('Header'))
sb[0].add(SOAP::SOAPElement.new('Body'))
sb[0]['Header'].add(SOAP::SOAPElement.new('MessageID', "000000")) sb[0]['Body'].add(SOAP::SOAPElement.new('Operation'))
sb[0]['Body']['Operation'].add(SOAP::SOAPElement.new('Query', 'This is my query'))
sb[0]['Body']['Operation'].extraattr['OperationName'] = 'QueryRequest'
sb[0]['Body']['Operation'].extraattr['OperationType'] = 'My type'


...

@resp = driver.invoke(sh, sb)

...

code = @resp[1]['Message']['Body']['Operation']['Responses'] ['Response']['Reference']['Code'].data
0.upto((@resp[1]['Message']['Body']['Operation']['Responses'] ['Response']['Records'].members.size rescue 0) - 1) do |r|
  puts @resp[1]['Message']['Body']['Operation']['Responses'] ['Response']['Records'][r]['Id'].data
end

Salud¡

viernes, 14 de septiembre de 2007

Memory leaks re-revisited

De nuevo, mejorando lo que hay.

La extensión de Time mucho mejor así:

class Time
  def method_missing(method_name, *args)
    cadena = self.strftime('%Y/%m/%d')
    return cadena.send(method_name, *args)
  end
end


Gracias Javi por tu ayuda.

Salud¡

Memory leaks revisited

Qué hay de nuevo?

He tenido que apretar un tornillo que se había quedado suelto con el tema del cambio en el acceso a sqlserver. Ocurre que, con ADO.rb, los datos de tipo datetime eran devueltos como Time si se obtienen a través de un modelo o como String si se obtienen mediante una query directa a la base de datos. Con ODBC siempre son devueltos como Time.

Por ello he tenido que extender el objeto Time para que no casquen los accesos con [], por ejemplo, en los casos en los que ADO.rb retornaba String.

En environment.rb (o mejor en algún fichero incluido en éste):

class Time
  def [](range = nil)
    return self.strftime('%Y/%m/%d')
  end
end

Salud¡

jueves, 13 de septiembre de 2007

Memory leaks conectando a sqlserver

Danimata al aparato.

Llevo N días viendo cómo una de nuestras aplicaciones, que trabaja contra sqlserver, padece de alzehimer, quicir, pierde memoria con cada petición.

Mi conexión era la siguiente:

adapter: sqlserver
database: dddddd
username: uuuuuu
password: xxxxxx
host: hhhhhh

Mi amigo Xavi me ha pasado un par de links en el que esto mismo le ocurre aquí y allá a otras personas que trabajan contra sqlserver a través de ADO.rb de la librería ruby-dbi. Recomiendan pasarse a ODBC.

He creado el origen de datos y mi conexión ha quedado como sigue:

adapter: sqlserver
database: dddddd
username: uuuuuu
password: xxxxxx
host: DBI:ADO:Provider=SQLOLEDB;Data Source=midatasource;

Lo he hecho, y nada de nada, el alzehimer continúa. Claro que no me había deshecho totalmente de ADO.rb. De nuevo Xavi con la solución. Con lo que me queda la siguiente conexión:

adapter: sqlserver
mode: odbc
dsn: my_dsn
database: dddddd
username: uuuuuu
password: xxxxxx

Et voilá¡ Todo funcionanado sin pérdidas de memoria y con la sensación de que las conexiones funcionan mejor y más rápido.

Como siempre, salud¡

martes, 28 de agosto de 2007

Dime con quién andas y te diré que RESCUE necesitas

Últimamente estoy decubriendo el uso de rescue y creo que estoy enamorado. Estamos acostumbrados a picar conociendo al dedillo lo que puede ocurrir y lo que no en la ejecución de nuestros programas y eventualmente dejamos de lado el control de errores. rescue no sólo ayuda en esta tarea sino que además se integra camaleónicamente el código de forma que apenas impacta en el mismo.

I love rescue.

viernes, 17 de agosto de 2007

Link interesante

Madre del amor que abandonado tengo esto.

El día 29 nació mi 'segundo proyecto a largo plazo'. Se llama Samuel y es tan bueno como su hermano Hugo.

A lo que iba: mi amigo Diego me ha pasado este link con un minitutorial de ActiveRecord bastante completo.

Tengo pendiente comentar el manejo de documentos Word y Excel. No se me ha olvidado pero me faltan manos y horas.

Como siempre, salud¡

jueves, 19 de julio de 2007

Una red social y una aplicación de facturación

Mi amigo Xavi Noria está a punto de terminar facturagem, la nueva ASP que ASPgems pone a disposición de autónomos, pymes y medianas empresas para la gestión de sus facturas.

Por otra parte, hemos participado en el desarrollo de dialogo, una red social 100% española que está pegando fuerte.

Como siempre, salud¡