Curso gratuito sobre Google AdWords en Madrid

Mis amigas de Dabne organizan un curso gratuito de publicidad con Google AdWords dirigido a asociaciones, cooperativas, fundaciones u ONG, de 20 horas de duración.

Te puedes apuntar desde la página de inscripción y saber más en su blog.

Curso gratuito sobre Google AdWords

¿Me va a funcionar una campaña de marketing en Google? ¿Cómo elijo las palabras clave para anunciarme? ¿Podré ver de dónde recibo los ingresos?

Curso gratuito de veinte horas de duración dirigido a trabajadores/as de asociaciones, cooperativas, fundaciones o ONG, impartido por Dabne con la colaboración de la Unión Madrileña de Cooperativas de Trabajo Asociado.

El curso de impartirá viernes por la tarde y sábados por la mañana, y es de próximo inicio.

http://dabne.net/inscripcion

Grupo Freelance Girona, y taller sobre Pylons

Este año comienza con la materialización de un proyecto que venía pensando con Jordi Catà, de D-Unlock: la consolidación de una red de freelances / cooperativas / pequeñas empresas dedicadas al desarrollo web con software libre en la provincia de Girona.

Nuestro objetivo es formar una red de profesionales dedicados al desarrollo web con software libre en Girona, y difundir el conocimiento de estas herramientas mediante charlas y talleres públicos.

Por el momento tenemos una lista de correo y un calendario de eventos.

En el 2007 yo dirigí un taller sobre arañas web con Ruby on Rails; para el 2008 tenemos por el momento un taller dedicado a un framework para Python:

Python Web Development: Pylons

Descripció: El llenguatge Python, no es conegut de forma massiva, no
obstant se està consolidant com un llenguatge molt flexible i potent per
el desenvolupament d’aplicacions web. En els últims anys han sorgit
diferents web frameworks basats en aquest tipus de llenguatge que permet
un desenvolupament àgil i robust d’aplicacions web. Es farà un especial
enfasis en Pylons, el primer framework que està desenvolupat seguint
estrictament el protocol WSGI.

A càrrec d’Ignasi Martín, Freelance web.

Dia 14 13 de febrer a las 20:00 en la Sala d’actes P4 (Escola Politécnica
superior, campus de Montilivi, Girona)

ACTUALIZACIÓN: la charla sobre Pylons ha sido cancelada, tenemos una nueva charla

Tutorial: recursos anidados con REST y Rails 2

Aunque el tema de REST y ActiveResource está disponible en Rails 1.2, hasta ahora ha sido un tema que he ido posponiendo en mi lista de cosas por aprender.

La introducción de REST por defecto en la generación de scaffolds de Rails 2 ha cambiado las cosas, y me ha hecho ver que no puedo dejar para más adelante el actualizarme a la filosofía REST.

He estado haciendo algunas pruebas para aclarar las ideas, así que aquí os dejo los códigos para que podáis echarle un vistazo, aprender conmigo y dejarme comentarios… seguro que he pasado por alto algunas cosas.

El objetivo de este tutorial es practicar los recursos anidados. Queremos construir una aplicación típica, un blog, pero en este caso, multiusuario. Tendremos N usuarios, cada uno de los cuales tiene M posts, y cada post tiene Z comentarios. Lo que buscamos es poder definir rutas REST anidadas, de manera que cada recurso (usuario, post, comentario) sólo tenga sentido dentro del contexto de su padre. En concreto, queremos rutas como estas:

# Listado de usuarios
/users

# Un usuario determinado
/users/:user_id

# Posts de un usuario determinado
/users/:user_id/posts

# Un post determinado de un usuario determinado
/users/:user_id/posts/:post_id

# Comentarios de un post y usuario determinados
/users/:user_id/posts/:post_id/comments

# Comentario determinado de un post y usuario determinados
/users/:user_id/posts/:post_id/comments/:comment_id

Como se ve, son rutas muy limpias y autoexplicativas.

Os explico en rasgos generales lo que hay que hacer para conseguir esto. Tras crear nuestra aplicación y la base de datos, generaremos los 3 scaffolds para controlar nuestros 3 recursos (users, posts y comments):

rails blog
cd blog
rake db:create
script/generate scaffold User name:string
script/generate scaffold Post title:string body:text user_id:integer
script/generate scaffold Comment body:text post_id:integer
rake db:migrate

Los scaffolds generarán los modelos y migraciones, controladores y vistas, etc. Además, introducirán rutas REST por defecto para cada modelo, pero las tenemos que cambiar porque no queremos que sean independientes, sino anidadas. Esto es, no queremos gestionar un post fuera del contexto de su usuario, ni un comentario fuera del contexto de su post y del usuario de este post.

Para ello, edita config/routes.rb, y elimina estas 3 líneas:

map.resources :comments
map.resources :posts
map.resources :users

Y pon en su lugar esta ruta anidada:

map.resources :users do |user|
   user.resources :posts do |post|
     post.resources :comments
   end
 end

Ahora, edita los modelos e introduce la relación entre ellos como de costumbre en Rails:

class User < ActiveRecord::Base
   has_many :posts, :dependent => :destroy
 end

class Post < ActiveRecord::Base
   belongs_to :user
   has_many :comments, :dependent => :destroy
 end

class Comment < ActiveRecord::Base
   belongs_to :post
end

Ahora, tendremos que modificar los controladores y vistas, porque fueron generados sin tener en cuenta que estarían anidados, así que hemos de actualizarlos. El controlador de usuarios (user_controller.rb) no necesita cambios porque es independiente de los de posts y comentarios.

Donde sí necesitamos cambios es en el controlador de posts. En primer lugar, necesitamos asegurar que un post sólo tiene sentido dentro del contexto de un usuario determinado, que se habrá pasado en la URL. Así que usaremos un filtro before_filter para que, antes de realizar cualquier acción, coja este usuario:

  before_filter(:get_user)

El método get_user lo definiremos así, dentro del apartado de métodos privados ya que no se usa más que desde dentro de este controlador:

private

def get_user
   @user = User.find(params[:user_id])
end

Ahora, modificaremos el resto de los métodos para que no se busquen los posts en general, sino dentro del contexto del usuario. Por ejemplo, en el método index, que lista los posts, en lugar de mostrarlos todos con:

@posts = Post.find(:all)

Mostraremos sólo los de ese usuario:

@posts = @user.posts.find(:all)

Modificaremos de manera similar el resto de acciones, para buscar el post a mostrar, crear, modificar o eliminar dentro de la colección de posts del usuario. En lugar de:

@post = Post.find(params[:id])

Usaremos:

@post = @user.posts.find(params[:id])

Esto nos añade seguridad ya que por ejemplo para editar un post, hay que indicar no sólo su id sino también su user_id, y si no son válidos, no lo encontrará.

Dentro del controlador también hay que cambiar las redirecciones, ya que por ejemplo tras crear un post, para redirigir al “show” de este post venía así recién creado el scaffold:

redirect_to(@post)

Ahora, como se trata de un recurso anidado dentro del usuario, hay que indicarle la ruta completa así:

redirect_to(user_post_url(@user, @post))

Echa un vistazo a los códigos de ejemplo que adjunto en este tutorial para ver el resto de modificaciones en este controlador.

El controlador de comentarios (comment_controller.rb) necesitará modificaciones similares, pero esta vez además del usuario hemos de recuperar el post, para tener el contexto completo. Es muy similar al ejemplo anterior, primero usamos los siguientes before_filter:

before_filter(:get_user)
before_filter(:get_post)

Y los definimos así:

private

def get_user
   @user = User.find(params[:user_id])
end

def get_post
   @post = User.find(params[:user_id]).posts.find(params[:post_id])
end

Fíjate en que podría haber cogido el post directamente pero para mayor seguridad lo estoy cogiendo a través del usuario.

Las redirecciones también serán similares. Por ejemplo, tras crear un comentario y redirigir al comentario, sería así:

redirect_to(user_post_comment_url(@user, @post, @comment))

Como ves, es similar pero indicando el usuario y post y comentario a que quieres redirigir.

También será necesario que edites todas las vistas de posts y comments, ya que los helpers generados por el scaffold no te valen, y has de indicar el contexto en todos. Por ejemplo, el enlace para crear un nuevo comentario será así ahora:

link_to 'New comment', new_user_post_comment_path(@user, @post)

Eso es todo por mi parte… Os dejo a continuación los códigos de este ejemplo para que podáis ver cómo he construido el resto de rutas con la ayuda de los helpers de Rails 2.0.2.

Códigos del blog rest con rutas anidadas

Seguro que he cometido unas cuantas correcciones, por lo que os agradecería que me lo indicarais con vuestros comentarios.

Boris en Slicehost

Boris, la araña, tiene ahora una nueva casa. Dreamhost se le ha quedado pequeño y se ha mudado a Slicehost:

http://www.borispider.com

Y es que, tras un mes de funcionamiento desde el último reseteo, ya manejaba más de 280.000 páginas y 132.000 keywords.

Su nuevo hogar es un servidor dedicado virtualizado, con Debian Etch, 256 Mb de Ram, o sea, el más pequeñito. En lugar de Apache + FastCGI como tenía en Dreamhost, ahora usa nginx + mongrel (un cluster de 2 mongrels). En vez de usar script/runner cada minuto para explorar las páginas, uso una rake task en bucle infinito.

Los tiempos de respuesta han mejorado muchísimo. Probé a cargar todos los datos y a comparar el rendimiento con siege, y este es el resultado con 5 conexiones concurrentes que repiten cada llamada 10 veces:

En http://boris.railes.net (Dreamhost)…

Transactions:                     50 hits
Availability:                 100.00 %
Elapsed time:                 137.10 secs
Data transferred:               0.29 MB
Response time:                 13.14 secs
Transaction rate:               0.36 trans/sec
Throughput:                     0.00 MB/sec
Concurrency:                    4.79
Successful transactions:          50
Failed transactions:               0
Longest transaction:           20.67
Shortest transaction:           9.14

En http://borispider.com (Slicehost)…

Transactions:                     50 hits
Availability:                 100.00 %
Elapsed time:                   7.14 secs
Data transferred:               0.30 MB
Response time:                  0.70 secs
Transaction rate:               7.00 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                    4.92
Successful transactions:          50
Failed transactions:               0
Longest transaction:            0.80
Shortest transaction:           0.66

En resumen, tanto Boris como yo estamos muy contentos. Hasta se le ve menos agobiado, y ya estima que no necesitará 273 años para terminar de indexar la web. Ahora sólo necesitará 16 años. :D

Ánimo, Boris!

Taller de Ruby on Rails en Sevilla

Factoria Web 2.0Mañana cogeré un avión para acercarme a Sevilla, donde he sido invitado por mis amigos de Flowers in Space para dar una clase sobre Programación con Ruby on Rails.

Esta clase que impartiré forma parte del proyecto Factoría Web 2.0, que pretende crear un vivero de proyectos web:

Este proyecto contempla la creación de un centro de nuevos proyectos
empresariales de Internet, especializado en la Web 2.0., el cual se denominará “Factoría Web 2.0” cuya ubicación será en el CADE de Sevilla.

La idea nace bajo la filosofía de funcionamiento de los viveros de empresa con el empleo de la metodología de “Simulación empresarial” aplicada en un entorno real.

Para ello se crearán grupos de tres personas (entre los universitarios participantes en el programa) que representarán los miembros de cada negocio virtual, cuya misión será la de programar cada Web 2.0. y realizar un plan de negocios atractivo para cualquier agente inversor (venture capital, business angel, seed capital, empresas del sector, etc.).

En este proyecto participarán otros ponentes como Xavier Noria, Luis Villa o Agustín Cuenca, entre muchos otros.

ACTUALIZACIÓN: Aquí están la presentación y los códigos de ejemplo: Introducción a Ruby on Rails

NURbijou, tienda online con Ruby on Rails

Un anillo para que lo compren todos…Esta semana estamos promocionando la nueva web de NURbijou, una tienda online dedicada a la venta en Internet de joyas traídas directamente desde la India.

Es un proyecto que nos ha ilusionado desde el principio, porque se trataba de la primera tienda que programábamos íntegramente con Ruby on Rails, dejando en el pasado las tiendas demasiado complejas y engorrosas que se consiguen con software basado en OSCommerce.

NURbijou es una tienda programada desde cero, con las características que necesitabamos y nada de lo que no nos hacía falta. Un catálogo de productos con fotos asociadas, y organizado por tags, una cesta de la compra, una gestión de usuarios minimalista y un gestor de contenidos para las páginas de información general.

En este proyecto hemos trabajado dos personas: por un lado Mar M. Núñez, de N/Ez, en el diseño gráfico, y por otro yo a la programación Ruby on Rails.

http://www.nurbijou.com

MetaInspector, mi primera gema ruby

Tras leer este magnífico tutorial sobre cómo publicar gemas con Hoe, he probado a crear mi primera gema en RubyForge.Se trata de MetaInspector, el corazón de Boris, la araña. MetaInspector facilita la extracción de datos de páginas web, encargándose de visitarla, descargar su HTML, y devolverte los datos de esa web: título, meta description y keywords, y enlaces.

Cómo instalar
sudo gem install metainspector

Ejemplo de uso

require 'metainspector'
datos = MetaInspector.scrape('http://www.google.com')
puts datos['title']
puts datos['description']
puts datos['keywords']
puts datos['links'].size

La web oficial de MetaInspector es:http://rubyforge.org/projects/metainspector/Se agradecerán vuestras pruebas y comentarios!

Códigos del taller de arañas web

2061499039_88e695f36f_o.jpgEn la edición de este año 2007 de la Conferencia Rails presenté un taller dedicado a la creación de una araña web con Ruby on Rails, usando open-uri, expresiones regulares, la gema Hpricot, el plugin acts_as_taggable_on_steroids, y tareas en background con script/runner y rake tasks.

Aquí está la presentación y los códigos completos de la aplicación de ejemplo, todo disponible con licencias libres:

Taller arañas web

(Foto cedida por Juanjo Bazán)

Ponencia sobre Web spidering, este viernes

Finalmente llegó! Tras meses de preparación, toca la segunda Conferencia Rails.

Este año, además de participar como organizador, lo haré también como ponente, presentando un taller práctico donde veremos cómo programar desde cero una pequeña araña web, como Boris, la araña.

Nos vemos!

Ponente Conferencia Rails

Taller de Web Spidering con Rails en Girona

El próximo miércoles 14 de noviembre dirigiré un taller sobre web spidering con Ruby on Rails en Girona.

La idea es explicar cómo podemos, mediante Ruby, descargar una página y extraer de ella sus datos (por ejemplo título, descripción, keywords…), usando expresiones regulares y la gema Hpricot; y mediante Rails, facilitarnos la tarea de almacenar estos datos en una base de datos con interfaz web, organizando las keywords usando un plugin como acts_as_taggable_on_steroids.

Veremos también cómo automatizar tareas en background (script/runner, rake tasks, cron) para que nuestra araña esté dia y noche extrayendo datos de la Web como lo hace, por ejemplo, Boris, la araña.

Me gustaría que este fuera el primero de una serie de talleres abiertos a todos los programadores interesados en estos temas, y no orientarlo a una charla de una sola persona sino como un grupo de trabajo donde compartamos ideas y experiencias. Tanto si quieres aprender como si tienes algo que aportar, vente!

El taller será el miércoles 14 de noviembre a las 18:30 en el local de D-Unlock:

C/ Riera Bugantó num 1, baixos 3, Girona

El taller es libre y gratuito, no hace falta reservar pero como sólo cabremos como mucho 10 personas, estaría bien que nos avisaras si vas a venir, para hacernos una idea…