Publicidad:
Terra
La Coctelera

Mis Tags > rubyonrails

Hay 31 artículos con el tag rubyonrails.

Otros artículos en La Coctelera
clasificados con rubyonrails

Sobre el papel Google Website Optimizer parece una herramienta de marketing estupenda. Nos permite definir unos objetivos y probar distintos contenidos o alternativas de una misma página para ver qué funciona mejor. El problema es que para ponerlo en marcha hacen falta dos ingenieros de caminos algunos conocimientos técnicos.

Tras seleccionar los objetivos google nos da huellas javascript para poner en cabeceras, pies, rodear secciones... Esta página da verdadero pavor la primera vez que la ves. No es de extrañar que antes de asustarte pregunte si lo vas a instalar tú o vas a contar con un equipo técnico para instalarlo.

Como miré en mis cajones y no encontré ningún 'web team' me imaginé que esto iba a tener que acabar probándolo en mis propias carnes, así que pensé ¿que haría McGiver?, o mejor, alguien más vago ¿qué haría Porras?. Evidentemente algo que me quitase de trabajar más de una vez en esto.

Buscando lo que había hecho por ahí encontré este plugin, que incorporaba unos helpers monísimos pero no me valía por tres cositas:

  • GWO es para usarlo una temporadita, decidir qué contenido es el que nos da mejor rendimiento y olvidarlo. Así que si puedo evitar modificar la aplicación mejor.
  • Tengo que incluir scripts concretos en páginas concretas. Si todas mis páginas comparten layout y quiero tener varios experimentos activos al mismo tiempo me toca montar la fiesta del 'elsif' o alguna similar, y... si puedo evitar modificar la aplicación mejor.
  • Si esto del GWO al final es buena idea, que parece que sí, van a querer usarlo en más sitios, y si yo o cualquiera de los agraciados podemos evitar modificar las aplicaciones... mejor!

Así que lo descarté y traté de construir algo que cumpliese con todo lo anterior.

Y de la vagancia más absoluta ha salido la primera versión de gwo_on_rails, un pequeñisimo plugin que te permite integrar este servicio tirando de un triste (pero bonito) yaml.

Está por limpiar, refactorizar y podar, amen de hacer tests más robustos, pero la realidad es que simplifica bastante el trabajo y ya está funcionando en un site en producción, en una home, a las mil maravillas sin modificar para nada la aplicación: instalar y rellenar el fichero de configuración.

¿Se puede pedir más? seguro que sí, hay partes que seguro se pueden resolver de formas más eficientes y otras que se a ciencia cierta que son un poquito matar moscas a cañonazos, así que cualquier sugerencia para mejorar el plugin será recibida con los brazos abiertos.

Hoy hemos hecho un import masivo de imágenes a una web, y han quedado así, tan bonitas con todos sus tamaños bien buestos gracias a attachment_fu (vía RMagick).

Cuando he ido a la web a comprobar qué tal quedaba todo me he dado cuenta de que los thumbnails generados descargaban lentitos, así que por pura casualidad me dió por mirar el tamaño de cada imagencita de 50x50 pixeletes de nada.

Mmmm.... 60kb!!!! WTF!!!!

Vale, tranquilidad... es un error... voy a mirar mi importación en local que seguro que está mejor.

Pues mira no, está igual :)

La primera solución, y la más obvia, es la de tocar la calidad de la imagen en la importación en rmagick, de hecho <a href="http://sobrerailes.com/">Lupión</a> me envió este post donde incluso te hablan de tocar la imagen de forma selectiva en función del thumbnail.

Así que nada... toco mi métodito en attachment_fu y le casco una calidad de 70 y... ya está!!

Reimportamos mientras me tomo un cafetito y... ale, ha terminado. Esto no puede haber salido mal, pero por si las moscas voy a ver qué ocupa la misma image de 50x50.

Aha... 45kb... mecagoen!!!!!

Antes de sacar el hacha vamos a ver qué puede tener esa imagen. Command + i y...

Aha... así que este thumbnail se ha hecho con una nikon :)

El caso es que RMagick al manipular una imagen no nos elimina ni los posibles comentarios y notas que pueda tener la imagen, ni ninguno de sus perfiles, ni exif... vamos, que se viene con todos los metadatos puestos. En una imagen mediana o grande tal vez esos Kbs de más no molesten, pero en cositas tan pequeñas yo prefiero eficiencia a sobreinformación.

Podemos ser mucho más selectivos, pero por lo general el comando strip! es nuestro amigo :) De este modo en vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb, en el método resize_image, retocamos esta linea:

 self.temp_path = write_to_temp_file(img.to_blob)
 

Por esto:

 img.strip!
 self.temp_path = write_to_temp_file(img.to_blob {self.quality = 70})
 

Lo de la calidad es opcional, RMagick usa por defecto el 75% de calidad, que es válida para un montón de casos.

Así que volvemos a lanzar la importación... 3... 2... 1... y a ver. Esta vez no nos esperamos a que acabe :) Et voilà! Su imagen de 4Kb!

Cosa fina!

Para ti, pequeño maquetador en proyectos rails :) En un proyecto normal las vistas tienen una jerarquía y están "donde deben de estar"™. El problema viene cuando la cosa se complica y hay partials compartidos, vistas que se reciclan y empiezan las particularidades.

Toda esa información está en el log. En mi caso uso este truquito cuando me tengo que centrar en solucionar sólo problemas en vistas y necesito ir al grano. Arrancamos el server de desarrollo con:

 	script/server | grep Render
 

o directamente sobre el log:

 	tail -f development.log | grep Render
 

De esta manera la salida que nos devuelve es más o menos así:

 	Rendering template within layouts/application
 	Rendering sessions/new
 	Completed in 0.01080 (92 reqs/sec) | Rendering: 0.00938 (86%) | DB: 0.00000 (0%) | 200 OK [http://0.0.0.0/login]
 

Y de esta forma localizamos la vistas a la primera :)

Mamá, los 404 no me dejan ver el bosque!

De vez en cuando llega la invasión de los 404. Normalmente son imágenes que no encuentra, y que puede ser por miles de motivos. Si la cantidad de errores es abusiva podemos hacer:

 	tail -f development.log | grep -v 404 | grep Render
 

Y ya está :)

unvlog.com

Hoy es un día de esos en los que sueltas al mundo algo en lo que has puesto mucha ilusión, y la verdad estoy muy contento :)

Hace un puñao de meses alberto puso este twitt. En un par de días blat, alberto y yo estábamos en un bar (donde se forjan los proyectos de verdad) hablando de esto. Alberto tenía una idea, y nosotros podíamos construirla.

Y así al final cada uno hemos puesto nuestro pequeño granito de arena, pasando por épocas buenas, malas e incluso un agosto hemos ido haciendo unvlog. A todo este esfuerzo se han unido las ilustraciones de dos señores estupendos como son dani (arriba) y puño (abajo). He de decir que todo el mundo flipa con las ilustraciones (tweet) y no es para menos.

Hace muy poquito empezamos con las cuentas para amiguitos, y fue cuando empezamos a notar que todo el cariño que se había puesto en el proyecto venía de vuelta cuando gente que te importa y a la que respetas habla maravillas (me dejo tweets, lo se).

Como colofón a tanta felicidad el viernes presentamos a la criatura en sociedad. Esperemos que nos acojan con el mismo cariño que todos los que ya habitan vuestro unvlog.

Para el tiempo libre

Dos cositas que estoy revisando a ratitos libres:

P.D. El blog en estos momentos no se termina de ver bien... ¿por qué? pues por la máxima esa de la casa del herrero y las cucharas de palo :D

Me encanta cycle

La primera vez que me encontré con blat habló del helper cycle.

Hoy haciendo una pruebecita lo he vuelto a usar, y me encanta que rails venga con estas tonterías de serie.

Así que cuando tengais que hacer una tablita y aplicarle un pijama (o hacer que elementos alternos tengan clases distintas):

 <tr class="<%= cycle("oscuro", "claro") %>">
      [... lo que sea]
 </tr>
 

Estoy de acuerdo con que 'el precio de la magia' (nando tm) a veces juega malas pasadas, y que a veces hay atajos que tocan las narices en cuestiones de rendimiento, pero esto es genial y rápidito.

Llegó la 1.2 de rails...

... y con ella el upgrade/susto. Durante unas horas han habido gemas con errores en el aire. Yo he sido una víctima de la actualización. Una cosa que no funciona, un upgrade de una gema y cuando te quieres dar cuenta tienes la 1.2 con unos cuantos errores al compilar.

Hay que reconocer que en un tiempo razonable han puesto remedio a los fallitos.

Ahora con el cambio de versión nos vienen las revisiones de los métodos obsoletos a los que tendremos que ir perdiendo la costumbre. Y si no mirad el mensajito que me deja el log de una aplicación cuando encuentra algo:

 DEPRECATION WARNING: The :dependent => true option is deprecated and will be removed from Rails 2.0.  Please use :dependent => :destroy instead.  
 See http://www.rubyonrails.org/deprecation for details.
 

Imagino que no todos los 'deprecated' serán tan educados y que nos vamos a dar algún que otro cabezazo cuando algo falle y no esté documentado.

Actualmente la página a la que nos refiere el log está vacía, imagino que en los próximos días se irá llenando.


Reconoced que el mensajito que nos han puesto, Nothing lasts forever, tiene un puntito de cachondeo :D

Mi buen amigo Sergio me sugiere una revisión del post anterior complicando un poquito más el baremo.

El nivel de desconexión en este caso se mediría tomando como base no el número de posts, sino el funcionamiento de bloglines:

Bloglines guarda un máximo de 200 items por feed (esto no lo he podido confirmar, pero seguro que googleando un poquito sale). Por tanto 200 x número de feed a los que estás suscrito => 100%. Así que sólo tenemos que compararlo con los items que nos faltan por leer, y el resultado será nuestro nivel de desconexión.

Esto se complica un poquito (por no decir bastante), más que nada porque la api de bloglines no nos deja sacar así por las buenas el número de feeds al que estamos suscritos, nos los devuelve en un opml monísimo, pero poco práctico para lo que nos hace falta. Para hacer eso nos pide que además de nuestro email de suscripción le demos nuestra contraseña (pero bueno, todo sea por saber cuanto estamos de desconectados).

Así que variaciones las variaciones con respecto al script anterior son:

  • Necesitamos el email y el password para poder pasar.
  • Tenemos que parsear el ompl que nos devuelva el listsubs.

De este modo nos quedaría una acción tal como esta:

     def desconector2
       
       begin
         bloglines = Bloglines::WebServices.new(:user => params[:username], :password => params[:password])    
         content = bloglines.listsubs
     
         @subscripciones = 0
         # parseamos el xml de subscripciones
         REXML::XPath.match(content, '//outline').each do |item|
           if item.has_attributes?
             @subscripciones = @subscripciones+1 if !item.attributes['xmlUrl'].nil?
           end
         end
     
         @maximo = @subscripciones*200
     
         @post_pendientes = bloglines.update
         desconexion = (@post_pendientes*100)/@maximo
         @resultado = "Estoy al #{desconexion.to_s}% de desconexion"
       rescue Exception => e
     
         @resultado =  e 
     
       end
         
     end
 

Para que hagais vuestras pruebas correspondientes he metido en mi routes.rb

     map.connect 'desconector/:username/:password', :controller => "bloglines", :action => 'desconector2'
 

Así que para probar podeis ir a http://mamuso.net/desconector/tuemail/tucontraseña.

Como se que no andan los tiempos como para ir dejando por ahí contraseñas en texto plano, debemos de buscar una alternativa. Otra forma de obtener el opml propio es a través de la página pública de blogroll. De esta manera los únicos datos que necesitaríamos serían nuestro email de suscripción y nuestro nombre de usuario para la página pública. Si no sabes cual es entra en la opción share de tu bloglines.

Por tanto unas leves modificaciones y… hecho:

 def desconector3
   begin
   
     bloglines = Bloglines::WebServices.new(:user => params[:username])    
     
     @subscripciones = 0
     # parseamos el xml de subscripciones
 
     url= "http://www.bloglines.com/export?id=#{params[:screenname]}"
     xmldata = Net::HTTP.getresponse(URI.parse(url)).body
     doc = REXML::Document.new(xmldata)
     
     REXML::XPath.match(doc, '//outline').each do |item|
       if item.hasattributes?
         @subscripciones = @subscripciones+1 if !item.attributes['xmlUrl'].nil?
       end
     end
 
     @maximo = @subscripciones200
 
     @post_pendientes = bloglines.update
     desconexion = (@post_pendientes100)/@maximo
     @resultado = "Estoy al #{desconexion.to_s}% de desconexion"
   rescue Exception => e
 
     @resultado =  e 
 
   end
     
 end
 

En el routes.rb:

     map.connect 'desconectorb/:username/:screenname', :controller => "bloglines", :action => 'desconector3'
 

De manera que podéis probar con http://mamuso.net/desconectorb/tuemail/tunombredeusuario.

Este baremo tampoco es perfecto, porque yo tengo feeds que no actualizan nada desde junio, por tanto si tienes muchos blogs de este tipo, tu nivel de desconexión será ‘irrealmente bajo’, además si estás suscrito a muchísimos blogs raramente pasarás del 5-10% con más de 2000 items sin leer. A lo mejor podríamos combinarlo con el nivel de desconexión que tienen nuestros suministradores de feeds hacia nosotros (uuuuh, esto se complica brothers!).

Como veis el fin de semana ha sido largo y aburrido. ¿Pensabais que este post era interminable? Yo también :D