miércoles, 7 de octubre de 2009

Resolviendo el error al instalar las guest additions de Virtual Box en Ubuntu 9.04 con ATI

Como siempre que me creo una máquina virtual nueva de Ubuntu 9.04 en VirtualBox (OSE), tengo problemas al instalar las Guest Additions.

Nunca me acuerdo de cómo se hacía, así que voy a ponerlo bien clarito aquí para que no se me olvide.

Antes de nada, mi equipo es un HP EliteBook 8530p, de esos que vienen con ATI (nunca más, lo prometo...). El sistema operativo que tengo instalado a día de hoy es Ubuntu 9.04 y la máquina virtual que voy a instalar es otro Ubuntu 9.04. Y dado que no soy ningún genio, me he tenido que seguir las instrucciones de este artículo, que es el que me dio la solución.

Ahora sí, empieza la chicha: después de crear una nueva máquina virtual, instalar el sistema operativo y montar el cd, abro un terminal (en la máquina virtual se entiende) y tecleo:

sudo /media/cdrom/VBoxLinuxAdditions-x86.run


Y el resultado es el siguiente:



¿Veis esas últimas líneas donde dice algo así como: Warning: unknown version of the X Window System installed. Not installing X Window System drivers?

Pues eso nos está indicando que tenemos un problema. Y si reiniciamos la máquina nos encontraremos con esta dichosa pantalla:





Bien, pues para solucionar esto, nos vamos al terminal y ejecutamos:

sudo /media/cdrom/VBoxLinuxAdditions-x86.run --target ~/guest_additions


Esto nos creará los archivos necesarios para la instalación de las guest additions en el directorio /tmp. Tenemos que editar el archivo install.sh (yo utilizo vim)


sudo vim ~/guest_additions/install.sh



Y en la línea 415 y cambiar Cambiar la línea siguiente:


1.5.99.* | 1.6 )


por


1.5.99.* | 1.6.0 )
1.5.99.* | 1.6.* )

Ahora ya podemos ejecutar el script de instalación:


sudo ~/guest_additions/install.sh


Y listos para reiniciar, y poder a utilizar nuestra máquina virtual con Ubuntu 9.04 y las guest additions funcionando correctamente.

A esto lo llaman la hora mágica. El día aún no ha terminado pero la noche aún no ha llegado, y en algun lugar Rocco Sifredi se está cepillando a una mujer que no ama -- Peter Griffin

martes, 6 de octubre de 2009

Las nuevas buenas maneras en el mundo 2.0

Tomándome una cerveza y viendo la tele, que es una de las mejores maneras de tener una idea divagar, me ha surgido la siguiente duda.

Con la implantación cada vez más rápida de la web 2.0 en nuestras vidas (el 24,7% de la población) están surgiendo nuevas maneras de comunicarnos (relacionarnos) entre todos nosotros. No voy a entrar en si la calidad de la comunicación mejora o empeora (igual en otro post me lanzo). Sí me gustaría, en cambio, reflexionar acerca de los nuevos códigos de conducta o protocolos que se van formando. En definitiva, qué es hoy en día una conducta social 2.0 aceptable.

Tengo claro que hay ciertos comportamientos sociales que funcionan de la misma forma en ambos escenarios: tanto en el mundo 2.0 como en el mundo 0.1-beta no suele ser buena idea insultar, descalificar o humillar (salvo que estemos en el parlamento, o en un plató de telecinco)

Hay otros, sin embargo, que mientras pueden suponer una conducta reprochable en uno de nuestros mundos, en el otro sencillamente no aplican. Me intentaré explicar:

Imaginemos a una pareja de concursantes en el Un, dos, tres, presentado por Mayra Gómez Kemp en cualquiera de sus etapas cuando este inventazo, que es internet todavía estaba en el huevo.

(Mayra Gómez Kemp): Ahora, por 374 pesetas, dígannos comportamientos sociales que no son bien aceptados, como por ejemplo, mascar chicle con la boca abierta haciendo ruido. Un, dos, tres, responda otra vez:


(Él): Mascar chicle con la boca abierta haciendo ruido

(Ella): Enseñar la ropa interior



(Él): Escupir en la calle


[...]

Bien, ahora imaginemos que se hace un remake del Un, dos, tres presentado por cualquiera de las presentadoras de la sexta (el Un, 2.0, tres)

(Pibón bendito): Ahora, por 2,25 euros, dígannos comportamientos sociales 2.0 que no son bien aceptados, como por ejemplo, CHATEAR UTILIZANDO EXCLUSIVAMENTE LAS MAYÚSCULAS. Un, dos, tres, responda otra vez:


(Él): CHATEAR UTILIZANDO EXCLUSIVAMENTE LAS MAYÚSCULAS

(Otro él): Copiar contenido de un blog personal sin dar referencias


(Él): Publicar fotos de un tercero en facebook y etiquetarle para que todo el mundo vea el pedo que se pilló la noche anterior a una reunión importantísima a la que no fue porque "se puso malo"



El problema que me he encontrado es que imaginándome esta última escena, no estoy muy convencido de que pudiera sacar demasiada pasta con esta pregunta. Yo sé qué es lo que a mí me parece una conducta poco apropiada, ¿pero será así para el resto? Me consta que no para todo el mundo, pero ¿cómo lo voy a saber si no he tenido una educación 2.0?

Así pues, me gustaría saber qué cosas os molestan de la red, qué buenas costumbres tenéis y creéis que sería bueno que más gente las practicara, o si realmente todo esto es una son paja mental mía...

Nota: Por si no hubiera quedado suficientemente claro quisiera aclarar que el término 2.0 ha sido utilizado de forma sarcástica en todo el artículo (como no podría ser de otra manera)

Pensar es el trabajo más difícil que existe. Quizá esa sea la razón por la que haya tan pocas personas que lo practiquen. -- Henry Ford

jueves, 1 de octubre de 2009

Internacionalización y localización en rails

Lo reconozco: soy un maniático de la localización e internacionalización. Tanto, que casi rozo un trastorno obsesivo compulsivo. En rails considero una práctica casi obligatoria incluir la localización desde el primer momento en que empezamos un nuevo desarrollo.

Pero como Rails está pensado para vagos, nos incluye, al menos desde la versión 2.3.2, el plugin I18n desde el principio. Con esto, simplemente tendremos que configurar nuestra aplicación para que utilice dicha funcionalidad (un punto más para rails!).

Para esto, lo primero es decidir dónde se van a colocar los ficheros yml de traducción. En mi caso siempre opto por ponerlos dentro del directorio config/locales/ de forma que crearé dentro de este directorio, otro más por cada idioma que quiera añadir a la aplicación. Por ejemplo:


config/locales/es-ES
config/locales/en-US


Después hay que decirle a la aplicación que cargue los diferentes archivos de idioma que tengamos en estos directorios. Para esto suelo crear el archivo de inicialización config/initializers/locale.rb


I18n.load_path += Dir[ File.join(RAILS_ROOT, 'config', 'locales', '*', '*.{rb,yml}') ]


Y por último hay que seleccionar el idioma con que queramos que se muestre nuestra aplicación. Para esto tenemos la variable I18n.locale. En el último proyecto en el que estoy, la aplicación sólo va a tener un idioma, por lo tanto bastaría con añadir la siguiente línea en el application_controller:


I18n.locale = 'es-ES'


Esta línea puede ser tratada para que coja la preferencia del usuario actual, por ejemplo:


I18n.locale = current_user.locale


Ahora necesitamos nada más crear los archivos de traducción en el directorio que hemos creado al principio. Estos archivos serán unos archivos yml. Por ejemplo un archivo con las cadenas de texto generales para toda la aplicación podría ser la siguiente:

config/locales/es-ES/general.yml


es-ES:
  general:
    add: Añadir
    are_you_sure: ¿ Estas seguro ?
    accept: Aceptar
    actions: Acciones
    back: Volver
    cancel: Cancelar
    delete: Borrar
    edit: Editar
    exit: Salir
    "no": "No"


Con esto ya tenemos configurada la aplicación para utilizar I18n.

Ahora para mostrar una cadena de texto traducida, podemos utilizar el helper I18n.translate o su alias t, de la siguiente forma:


t('general.accept')


Nos devolverá la cadena "Aceptar".

Esto es útil hacerlo hasta cuando vayamos a tener una aplicación con un solo idioma porque:

  1. Es más fácil mantener los textos de la aplicación si estos están contenidos en unos cuantos ficheros de traducción, que si estuvieran dispersos a lo largo y ancho de toda nuestra aplicación
  2. Siempre es posible que en un futuro nuestra aplicación tenga que ser traducida a otro idioma. De esta forma, simplemente tendríamos que replicar los archivos de traducción y traducir las etiquetas.
  3. Si no internacionalizamos, tendríamos que conformarnos con que cierta información se muestre como viene por defecto: por ejemplo, que el separador de miles sea la coma y no el punto, que la moneda sea el dolar, etc
Estos son los conceptos básicos para internacionalizar una aplicación. En otro momento, cuando tenga más tiempo y me encuentre con humor, intentaré explicar cómo traducir ciertos componentes de rails como los modelos, errores, unidades, etc. Eso sí, para el que le pique la curiosidad siempre estará nuestra amiga la web para resolver todas nuestras dudas.

Y como última recomendación uno de los mejores punteos bajo mi humilde punto de vista: Ram It Down de Judas Priest

Si el cerebro del ser humano fuera tan sencillo que lo pudiéramos entender, entonces seríamos tan estúpidos que tampoco lo entenderíamos -- Jostein Gaardner (El mundo de Sofía)

Validando en rails cuando necesitas acceder a current_user

Estoy en medio de un proyecto con acts_as_authenticated y me he encontrado con el problema siguiente:

A la hora de validar un modelo, necesito comprobar unos atributos del usuario actual. Es decir, necesito acceder a los atributos de current_user.

Sin embargo, dicha variable no está disponible en el modelo. Así que buscando en google encontré esta discusión, que me dio una posible solución.

El resumen es el siguiente:

Hay que crear un atributo de clase thread en User (o en la clase que tengamos definidas para almacenar los usuarios) que me devolverá el current_user:

class User < ActiveRecord::Base
  cattr_accessor :current_user
  def self.current_user
    Thread.current[:user]
  end

  def self.current_user=(user)
    Thread.current[:user] = user
  end

end

Luego, en application_controller, para que esté disponible siempre, se define un before_filter

class ApplicationController < ActionController::Base
  before_filter :set_current_user
private
  def set_current_user
    User.current_user = current_user
  end
end

De esta forma, se asigna al atributo de clase User.current_user, la variable current_user. Ahora basta con llamar a User.current_user para poder acceder a la información que estábamos buscando.

class Project < ActiveRecord::Base
  validate :my_validation
private
  def my_validation
    errors.add(:validating_attribute, 'validating_attribute_error') unless User.current_user.my_method
  end
end



"Si la industria automovilística hubiera seguido el mismo desarrollo que los ordenadores, un Rolls-Royce costaría hoy 100 dólares, circularía un millón de millas con 3,7 litros y explotaría una vez al año, eliminando a todo el que estuviera dentro en ese momento"
-- Robert X. Cringely