Un maño entre gaúchos

Oferta de becario para el área de sistemas de The Cocktail

dejar un comentario »

En The Cocktail Experience, empresa dedicada a la consultoría web, estamos interesados en contratar becarios para el área de sistemas. Gente con muchas ganas de trabajar y aprender.

El perfil que estamos buscando es el siguiente:

  • Experiencia con sistemas GNU/Linux.
  • Conocimientos básicos de scripting
  • Conocimientos básicos de servidores web y servidores de bases de datos (por ejemplo MySQL, Apache….)
  • Posibilidad de realizar convenio de prácticas

Si estás interesado, envía tu CV a: andrea.hidalgo ARROBA the-cocktail PUNTO com

Exportar passwords de revelation a texto plano con ruby

dejar un comentario »

Revelation tiene la opción de exportar el fichero de contraseñas a texto plano. El problema es que la organización de las entradas no es demasiado buena, porque las pone en una sola columna sin indentación, por lo que resulta dificil ver el anidación de las contraseñas en caso de que se usen carpetas.

Necesitaba tener las contraseñas en texto plano de forma que pudiese ver a simple vista esta información y fuese más facil de mantener. Esto se puede hacer fácilmente con ruby y xml-simple:

require 'rubygems'
require 'xmlsimple'

PASSWORD_FILE="./passwords.xml"

config = XmlSimple.xml_in(PASSWORD_FILE)

ce = config

indent = ""
INDENT_SPACES = "  "

def stepin(ce, indent)
  if !ce.nil?
    indent = indent + INDENT_SPACES
  end

  ce['entry'].each { |item|
    puts indent + item['name'].to_s
    if !item['entry'].nil?
      stepin(item, indent)
    elsif item['entry'].nil? && item['type'] != 'folder'
      if item['description'] && !item['description'].to_s.empty?
        puts indent + INDENT_SPACES + "description: " + item['description'].to_s
      end
      item['field'].each { |field_type|
        if !field_type['content'].nil?
          puts indent +
               INDENT_SPACES +
               field_type.values[0].gsub("generic-", "") +
               ": " +
               field_type.values[1]
        end
      }
    end
  }
end

stepin(ce, indent)

Para que esto funcione basta tener instalado rubygems y xml-simple.

Written by Luis

Abril 27, 2009 a 11:38 am

Estudio sobre el interés de la gente por los lectores de ebooks

con un comentario

The Cocktail Analysis ha realizado un estudio sobre el interés y el conocimiento que la gente tiene sobre los ebooks y los lectores de ebooks. Este estudio se puede leer aquí.

Personalmente, estoy de acuerdo con las primeras lineas del estudio que dicen que mucha gente estaría interesada en adquirir un lector de ebooks, solo que a un precio muy inferior del actual.

Hoy en día los lectores de ebooks más baratos cuestan cerca de 300€. No es un precio que esté dispuesto a pagar, sobre todo teniendo en cuenta que prácticamente acaban de nacer y las empresas que los comercializan no tienen bien definido el negocio de venta de libros digitales a través de lectores de este tipo. En mi opinión el que mejor montado lo tiene es Amazon con su Kindle, pero claro hablamos de que casi todos los libros que ofrecen están en inglés y que es un servicio, de momento, disponible únicamente para Estados Unidos.

Yo de momento voy a esperar a ver como se desarrolla la cosa.

Written by Luis

Abril 22, 2009 a 9:22 am

Return-Path en un mail desde Rails

dejar un comentario »

Pongamos la clásica funcionalidad web en la que un usuario lee una noticia y tiene el típico enlace “Mandar la noticia a un amigo” de forma que dicho amigo va a recibir un mail enviado por un servicio de noticias, pero va a saber que quien se lo ha querido enviar es su colega. Lo que necesito entonces es poder mandar emails desde rails que cumplan las siguientes condiciones:

  • La dirección de origen que aparezca en el email, es decir la cabecera From ha de ser una genérica asociada al servicio, como por ejemplo noreply@example.com.
  • El Reply-To ha de ser otra dirección, pongamos la del usuario que ha querido enviar el mail a su amigo.
  • Quiero estar seguro de que cada email que se envía desde este servicio se envía correctamente y si no lo hace, al menos conocer la razón de porque no ha sido así. Por lo tanto necesito que si falla el envío, el servidor SMTP donde ha fallado sea capaz de devolverme una respuesta para que mi sistema pueda ir parseando emails de respuesta de envios fallidos. Eso sí lo que no quiero es que estas respuestas vayan a parar al buzón del sistema del usuario con el que está arrancada la aplicación web, ya que se me pueden mezclar en ese buzón un montón de cosas y no solo las respuestas de esos envíos concretos de correo. Por lo tanto necesito poder indicarle a rails esa dirección de respuesta de errores. La cabecera que se encarga de proporcionarle está información a los servidores de correo es la de Return-Path. Pongamos que está dirección es fail@example.com

Así que el código de ejemplo de un envío de este tipo sería el siguiente:
En el config/environments/production.rb:


config.action_mailer.delivery_method = :sendmail

y en la clase del ActionMailer::Base:

class MessageMailer < ActionMailer::Base
  def message_email(email_data)
    recipients  email_data[:recipient]
    from        "noreply@example.com"
    headers     "Return-Path" => "fail@example.com"
    reply_to    email_data[:sender_email]
    subject     email_data[:subject]
    body        :body => email_data[:body]
  end
end

Si se tienen en la aplicación muchos métodos de envío de correos diferentes, para no tener que indicar siempre el header de Reply-To, se puede poner a mano en el environment como parametro de sendmail:

  config.action_mailer.delivery_method = :sendmail
  config.action_mailer.sendmail_settings = {
    :location => '/usr/sbin/sendmail',
    :arguments => '-i -t -f fail@example.com'
  }

Written by Luis

Abril 17, 2009 a 5:14 pm

ServerName y ServerAlias en Apache

dejar un comentario »

En el servidor web apache, dentro de un VirtualHost se puede incluir un ServerName para que Apache sepa que ha de aplicar la configuración contenida en ese VirtualHost a las peticiones dirigidas al DNS de dicho ServerName.
También se puede incluir uno o varios ServerAlias dentro del mismo VirtualHost por si el site definido en dicho VirtualHost puede ser accedido a través de más de un DNS diferente.

Ahora bien, la diferencia entre ServerName y ServerAlias es que el ServerAlias acepta wildcards y el ServerName no.
Yo puedo hacer lo siguiente:


<VirtualHost>
  ServerName example.com
  ServerAlias *.example.com
  ...
</VirtualHost>

pero no puedo hacer esto:

<VirtualHost>
  ServerName *.example.com
  ...
</VirtualHost>

Written by Luis

Abril 16, 2009 a 11:30 am

Una historia de capistrano, crontabs y pipes

con 2 comentarios

Al montar el deploy de una nueva máquina con capistrano he querido afinar un poco la carga de crontabs.
No me gusta poner las tareas de crontab en el /etc/crontab. Creo que es una muy mala práctica. En vez de eso prefiero que cada usuario tenga su propia tabla de crontabs y para ello hago uso del comando crontab.
En muchas ocasiones hace falta definir crontabs para más de un usuario. Para no andar añadiendo una linea en el script de deploy por cada fichero de crontab que se tenga doy por hecho que los nombres de todos los archivos con las tablas de crontab siguen el mismo formato, que es “crontab ..
El código pues para capistrano es:

task :app_deploy, :roles => [:app] do
  Dir["./appserver/etc/crontab.*"].each { |crontab|
    sudo "sh -c 'cat #{release_path}/#{crontab} | \
    crontab -u  #{File.extname(File.basename(crontab)).delete('.')} -"
  }
end

En este código hay varias cosas que explicar.
Primero se presupone pues que si quiero, por ejemplo, añadir el crontab para el usuario www-data simplemente lo crearé y lo guardaré en appserver/etc/crontab.www-data
En cuanto al código, por un lado el bloque lo que hace es cargar en un array los ficheros con un nombre que coincida con el patrón comentado anteriormente. Hay que tener en cuenta que el código en ruby se ejecuta en la máquina desde la que se lanza el deploy y lo que se le pasa al comando run o sudo es un comando unix que se va a ejecutar en la máquina en la que se quiera hacer el deploy.

Por otro lado está el hecho de que cuando se ejecutan con sudo dos comandos unidos por una tubería, el sudo se va a aplicar únicamente al primero.
Si se hace:


$ sudo echo '* * * * * date > /tmp/date' | crontab -u root -

el sudo se va a aplicar únicamente al comando echo y no al comando crontab por lo que eso no funcionará ya que no tenemos privilegios suficientes.

Por lo tanto para no tener que repetir el comando sudo a los dos lados de la tubería y también para no complicar el comando en capistrano, lo que se puede hacer es englobar toda la sentencia en una subshell de la siguiente forma:


$ sudo sh -c 'echo "* * * * * date > /tmp/date" | crontab -u root -'

Written by Luis

Abril 15, 2009 a 4:37 pm

Mejoras en la justicia

con un comentario

El sistema judicial funcionaría mejor si se hiciera uso frecuente de las bolsas de plástico y los mangos de las escobas.

Written by Luis

Marzo 18, 2009 a 3:32 pm

Para los que no saben sonreir

con 2 comentarios

Entrenador de sonrisas

Written by Luis

Marzo 15, 2009 a 12:50 pm

Oferta de consultor de Experiencia de Usuario

dejar un comentario »

En The Cocktail estamos buscando una persona para incorporarse al
equipo de Experiencia de Usuario como consultor.

Los candidatos deben cumplir con los siguientes requisitos:

- Experiencia en departamentos similares.
- Capacidad de liderazgo.
- Nivel medio/alto de inglés oral y escrito.
- Rigurosidad, capacidad de trabajo y profesionalismo.
- Excelentes capacidades orales y de comunicación escrita.
- Capacidad de trabajo en equipos multidisciplinares.
- Capacidad de transmisión de sus conocimientos al resto de la
organización.

Es fundamental que los interesados puedan demostrar sus habilidades en:

- Conceptualización de soluciones online, tanto en web como en
entornos móviles.
- Definición de requerimientos funcionales con usuarios.
- Arquitectura de información (flujos, inventarios de contenidos,
árboles de navegación, etc)
- Creación de escenarios de uso y modelado de usuarios (personas,
casos de uso).
- Prototipado (wireframing) de soluciones web.
- Documentación de proyectos.

Se valorará positivamente la experiencia en equipos de trabajo
multidisciplinares, definición de proyectos RIA y conocimientos de
conceptos de diseño y maquetación básicos.

Los interesados, por favor enviad los CV a: info@the-cocktail.com

Written by Luis

Marzo 10, 2009 a 10:52 am

Error al instalar passenger (fcgi)

dejar un comentario »

Al intentar instalar passenger a partir de la gema, me he encontrado con un error rarísimo. He estado un rato intentando ver que podía ser.
Al final me he cansado y he probado a cambiar la versión de rubygems de la 1.0.1 a la 1.3.1 y se ha instalado correctamente.
El error era el siguiente:

# gem install --no-ri --no-rdoc passenger
Bulk updating Gem source index for: http://gems.rubyforge.org
Building native extensions. This could take a while...
ERROR: Error installing passenger:
ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb install --no-ri --no-rdoc passenger
checking for fcgiapp.h... no
checking for fastcgi/fcgiapp.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/bin/ruby1.8
--with-fcgi-dir
--without-fcgi-dir
--with-fcgi-include
--without-fcgi-include=${fcgi-dir}/include
--with-fcgi-lib
--without-fcgi-lib=${fcgi-dir}/lib

Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/fcgi-0.8.7 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/fcgi-0.8.7/ext/fcgi/gem_make.out

Written by Luis

Enero 7, 2009 a 6:11 pm

Escrito en Sistemas, ruby

Tagged with , , , ,