viernes, 26 de octubre de 2007

Que viene, que viene.. uh¡ uh¡

Queda menos de un mes para la Conferencia Rails 2007 de Madrid y hace ya una semana que se ha cerrado la lista de ponencias. Voy a tener problemas para elegir en algunos casos.

Voy a tener que ir afeitado porque veo amigos y conocidos entre los ponentes: Javier Ramírez, Xavi Noria, Alberto Romero y Agustín Cuenca compartirán sus cositas con todos nosotros.

Suerte para todos¡

Esta semana hemos seguido dando candela a los crawlers con Firewatir, Mechanize y rest-open-uri y hemos accedido a algún que otro web service. Nada superinteresante.

Salud¡

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¡