De cero a treinta

7 Mar

La verdad es que no muchos podemos decir que hemos visto crecer la empresa en la que trabajamos desde los cero empleados hasta los treinta empleados. De hecho, todavía menos podemos decir que lo hemos visto varias veces. Y la verdad es que algunos podemos decir que también hemos visto ver decrecer de treinta a cero. Y ver todos estos casos es lo que hace que aprendamos algunas cosas muy importantes sobre las personas que incorporamos a la empresa.

Un buen producto sólo puede salir de un buen equipo. Pero el mejor producto solamente sale del mejor equipo. Por eso es muy importante que prestes atención a todos y cada uno de los candidatos que vas a contratar, porque un sólo candidato con malas cualidades puede arruinar el proyecto por completo.

Lo primero que tienes que tener claro cuando empiezas un proyecto, ya seas el fundador o uno de los primeros es entrar, es que cuando eres una empresa del tamaño de una Startup, la responsabilidad se reparte entre todos de manera equivalente -y si no lo es, entonces no estás empezando bien tu empresa. Por lo que aquella persona que contrates al principio tienes que tener en cuenta que es una persona en la que vais a poner mucha responsabilidad y además en la parte más crítica del proyecto. Por eso es recomendable que cuando vayas a contratar a alguien, si es de las primeras personas, te lo pienses muy bien. No solamente tiene que encajar en el perfil profesional, que es tremendamente importante, sino en el perfil personal. Una persona que encaje muy bien en el perfil profesional no vale lo mismo que una que también lo haga en el perfil personal. Son personas que van a pasar muchas horas encerrados contigo, y por tanto, la convivencia con ellas va a ser mucho más intensa que con empleados normales.

Cuando hablo del perfil personal, hablo de todos los aspectos del perfil personal. Tanto su carácter, como su sociabilidad así como su vida personal. Si, vida personal, eso es lo que he escrito. Aunque parezca agresivo, la vida personal de una persona que contratas al principio de tu proyecto va a ser tu vida personal también. Debido a la cantidad de esfuerzo tanto profesional como personal que dedicáis, vuestras vidas personales van a tener hilos en común, donde sufrirás los problemas de tus compañeros de trabajo al igual que ellos sufrirán los tuyos. Y es que no es nada desacertado cuando la gente habla no solamente de Startup sino de ser como una familia.

La edad no debería de ser una baza para seleccionar a una persona. De hecho, la experiencia siempre es un buen punto a tener en cuenta cuando contratas a alguien en una etapa tan crucial del proyecto. Pero también tienes que tener en cuenta que la edad también es una distancia entre las personas. Las horas que pasas junto a tus compañeros de trabajo genera un entorno de bromas, actividades sociales e incluso de confianzas que a veces la edad puede interrumpir o incluso minar. Ten en cuenta que la persona que entre al principio debe estar 100% alineado con el resto de tu equipo tanto profesionalmente como personalmente.

En segundo lugar, hay que mirar muy bien la actitud que tiene la persona con respecto al proyecto. Un candidato que vea el puesto de trabajo como algo temporal, o un sueldo que va a obtener al final del mes es un candidato perdido. Aquellos que miren tu proyecto como uno más no merecen ni que los mires. Son personas que no vas a conseguir enamorarles de tu proyecto, y si lo consigues, es tiempo que has perdido en vez de haber contratado a otro candidato.

Es preferible que contrates a alguien que tenga menos aptitudes profesionales pero que tenga un entusiasmo feroz por tu proyecto. Esta persona va a dejarse la piel por aprender todo lo que le falta hasta llegar al nivel que necesitas de él, e incluso más. El amor por un proyecto es importantísimo en un candidato. Es lo que hace que esa persona venga a la oficina a las siete de la mañana y que se quede durante quince horas contigo programando o organizando diseños o limpiando bases de datos. Esa diferencia puede ser determinante, así que analiza muy bien el interés de tus candidatos por el proyecto.

Aquí es igual de importante cómo sepas explicar tu proyecto. Y cómo lo vendas. La energía que pongas, las ganas que dediques y la manera en la que lo expliques va a dar más o menos oportunidades al candidato a entender lo que estáis haciendo en tu Startup. Ten en cuenta que no eres una empresa famosa y no hay artículos de prensa ni revisiones de tu producto por ahí que puedan leer. Simplemente una descripción del trabajo y probablemente un par de conversaciones con quien le haya organizado la entrevista. Si no lo vendes bien, no vas a enamorar a los candidatos, y menos a tus empleados o compañeros de trabajo.

Finalmente, lo que voy a decirte es una frase que tengo grabada a fuego en mi cabeza: los veinte primeros empleados son los que determinan el ADN de una empresa.

Así que cuando vayas a contratar a alguien para tu proyecto, y sea una de las veinte primeras personas que contratas, mira con mucha atención los puntos que he puesto, porque pueden ser claves para que tu producto sea el mejor.

Ahora bien, igual de importante que contratar a las personas adecuadas es el despedir a las personas inadecuadas. Suena mal, pero una persona inadecuada puede llevarse por medio a toda una empresa, que son muchos más que un solo empleado. En un estado tan crítico como una Startup no hay espacio para error. Es decir, tienes que ser capaz de reaccionar lo más rápido posible para que el proyecto siga adelante y no se quede por el camino. No puede haber gris, sólo blanco o negro. No hay tiempo para analizar o para evaluar, solo hay tiempo para ejecutar. Y el despido es tan importante como la contratación. Y si los despidos son complicados, como pasa por ejemplo en España, lo más aconsejable es hacer un acuerdo con el empleado que vas a echar, de manera que los dos estéis contentos. No hay nada peor para una Startup que un ex empleado no contento, que tanto aquí en Estados Unidos como en España te pueden poner el proyecto en la calle.

En una Startup la mejor situación es cuando no se tiene que ir nadie, porque significa que la contratación que estás haciendo es la adecuada. Ese es el escenario al que todos debemos luchar, donde debemos ser muy diligentes con las personas que incorporamos a nuestro equipo y muy exigentes con las pruebas y entrevistas que hacemos para que no se incorpore alguien que a la postre no será compatible con la forma de trabajar del equipo.

Por fin salimos a la luz

24 Feb

Hace ya un año y medio, en Noviembre de 2010, me puse en contacto con los tres amigos tanto de la carrera, como del paintball -esto merece otro post- y les comenté la idea de hacer un sistema de pago por móviles. Sin dudarlo, Fernando Ávila, Virginia Masa, Catalina Mayorga y Sebastián Vidal se pusieron en marcha y se vinieron a Santa Mónica para empezar un nuevo proyecto que ahora se llama Kuapay.

La historia en realidad es mucho más larga. Allá por el 2005, finalizada la carrera y llevando ya varios meses trabajando en Accenture, Fernando, compañero de carrera, se puso en contacto conmigo y me dijo que quería que viera una cosa que un amigo había visto en Estados Unidos. Dicho y hecho, nos fuimos a casa de Adeyemi y me pusieron delante de la pantalla donde estaba Facebook. Su pregunta: ¿Es posible hacer esto en España? y mi respuesta: «Dame un día y te lo enseño.». Así que me puse la manta a la cabeza, y con la ayuda de Fernando y Virginia, hicimos el primer prototipo, que tenía ya etiquetas en las fotos. Toda esta historia, con todos los detalles irán en otro post, porque hay muchas cosas que no se han dicho y que merece la pena escribirlas -sólo por lo graciosas que son.

Por esta historia común, decidimos volver a empezar otro proyecto, que es Kuapay. La idea fue ponernos delante de una pizarra blanca y pensar ¿cómo podemos hacer que los pagos sean mejor, y más seguros?. El proceso de pensamientos fue muy simple. Fuimos uno a uno poniendo todos los puntos que un pago, sea del tipo que sea, tienen que cumplir. Al final conseguimos una lista que es la que mantenemos a día de hoy:

1. El pago tiene que ser sencillo

2. Tienes que poder pagar con lo que tienes ya en tu mano

3. Tiene poder pasar sin tener que imprimir papeles

Con estos puntos en la cabeza nos pusimos manos a la obra. Para poder resolver estos problemas, lo primero que hicimos es ponernos una sola prioridad, la experiencia del usuario en el pago. A día de hoy la experiencia del usuario del pago es horrible. Tienes que introducir la tarjeta, introducir un PIN y luego recibir el papel con tu confirmación. En otros países incluso tienes que esperar a que el papel salga, y en vez de introducir el PIN tienes que firmar y posteriormente entregar tu papel firmado. Si estás en un restaurante, tienes que esperar a que te traigan un punto de venta para poder hacer este mismo proceso o dejar que se lleven tu tarjeta. Esto a nosotros nos pareció un buen punto de partida. Es decir, ¿por qué sucede esto? ¿por qué es tan mala esta experiencia? ¿cómo hemos llegado hasta este punto?. Y nos dimos cuenta de que actualmente estamos usando una plataforma de pagos que fue diseñada hace más de 40 años ya. Donde todavía la tecnología que tenemos a día de hoy era impensable. El simple hecho de que tengamos que llevar una tarjeta de plástico con nosotros ya nos da la idea de lo retrasado que está el mundo de los pagos.

Visa y Master Card están al corriente de esto y por esto están obsesionados con lanzar nuevas maneras de pagar que mejoren esta experiencia. Por eso han salido con productos como el NFC en el plástico o como Visa Paywave y Master Card Paypass. La innovación en realidad la lleva Master Card, que es el creador original del estándar mundial de NFC en tarjetas Paypass, que luego compartió con Visa y con American Express para promover la tecnología. Pero siguen teniendo el mismo problema de base, y es que lo que quieren hacer en transformar la capa más superficial de su plataforma de pagos, dejando las capas restantes como están. Es decir, cambiar la capa del plástico y el deslizado de las tarjetas en las tiendas, pero no quieren cambiar cómo funciona el resto de los componentes por detrás, como los procesadores de las tarjetas, los emisores, los agentes, etc.

Esto es lo que nos dio la clave de cómo debíamos atacar el problema. En Kuapay lo que tenemos que hacer es cambiar todas las capas del medio de pago. Es decir, no podemos hacer una solución que añada una capa más -como hace el NFC- o simplemente cambiar una sola capa -como hace SquareUp. Tenemos que cambiar el medio de pago por completo, y tenemos que ofrecer una solución que cambie radicalmente cómo se hacen los pagos. Una experiencia que sea legítima y de la percepción de un pago hecho y terminado. Una experiencia tanto para el usuario como para el comercio.

Así pues, nació Kuapay. Hemos trabajado muy duro para llegar hasta esta posición. Estamos en la segunda revisión de nuestro producto. Hemos hecho pilotos en más de 6 países, incluídos Estados Unidos y Chile. Somos un equipo de más de 30 personas trabajando en dos oficinas diferentes y tenemos la confianza de nuestros inversores detrás del proyecto aprobando todas y cada una de las decisiones que tomamos. Como por ejemplo, la decisión de no salir en ningún medio general hasta el congreso de Barcelona. O que los empleados de la empresa tengan más porcentaje que los inversores. O que todas las pruebas qu

e estuviéramos haciendo por le mundo fueran secretas.

Ahora tenemos la oportunidad de enseñar al mundo el fruto de nuestro trabajo durante los últimos 12 meses. ¡Bienvenido a la nueva forma de pagar!

Super Easy Template engine en Javascript

21 Jul

En Kuapay hemos diseñado y desarrollado un nuevo sistema de templates basado en el omnipresente clásico Mustache, que te ayuda a hacer una página web multi lenguaje sin el engorro de tener que crear HTML para cada lenguaje o de pre-compilar las páginas antes de crearlas, como sucede con los templates de PHP o Ruby.

Super Easy Template te ayuda a tener una página web en múltiples idiomas sin el tedioso paso de tener que compilar el código o usar ¨gettext()¨ en tu servidor, sino que es el cliente el que tiene la lógica de los templates en su navegador, y en consecuencia menos carga para tus servidores.

Super Easy Template te ayuda a crear templates en HTML donde en vez de colocar las palabras colocas placeholders a dichas palabras. Algo así:

<div class="basic">
  <h1>{{template_title}}</h1>
  <p>{{template_text}}</p>
</div>
<div class="flags"></div>

Tienes que tener un servidor web para poder poner en marcha el código.

Donde podemos ver los placeholders template_title y template_text. Para poner este template engine en marcha seguimos los siguientes pasos:

  1. Descargar el código del repositorio: https://github.com/kuapay/Super-Easy-Template-Engine
  2. Copia el contenido del repositorio completo al directorio base donde el servidor web tiene las páginas (en entornos linux suele ser /srv/www o /var/www).
  3. Reinicia el servidor web.

Accede a la página web de tu servidor web (normalmente http://localhost/index.html) y verás la siguiente página en tu explorador.

Ahora ya tienes tu página web en marcha. Lo que tienes que hacer es empezar a cambiar los templates y rellenar los archivos que contienen los diccionarios de locales. Aquí vamos a ver el ejemplo para poner un template nuevo, con su diccionario y sus idiomas.

Primer template

El primer template que vamos a introducir lo vamos a llamar nuevo.mustache. El nombre del fichero debe acabar en .mustache por una sencilla razón, y es que SET es compatible con más template engines que queramos incorporarle. Por ahora hemos introducido nada más Mustache. Dentro del archivo, que lo vamos a introducir en:

$WWW_HOME/templates/nuevo.mustache

El contenido del archivo va a ser el siguiente:

<div class="basic">
  <h1>{{template_title}}</h1>
  <p>{{template_text}}</p>
  <p>{{template_another_text}}</p>
  <div class="flags"></div>
</div>

Ahora vamos a añadir en el archivo de diccionario el contenido de este nuevo template. Abrimos locales/en_US.locale y añadimos el nuevo template:

    "6":  "Saturday",
    "7":  "Sunday"
  },
  "basic.mustache": {
    "title":  "This is the title of the basic template",
    "text":   "Text that explains what is this template about"
  },
  "nuevo.mustache": {
    "title":  "Title of my new template",
    "text":   "My new template has this text that is beautiful.",
    "another_text":   "And this second paragraph explains how to make paragraphs."
  },
  "flags.mustache": {
    "change_language":  "Change the language:",
    "spanish":          "into spanish",
    "english":          "into english"
  }

Puedes ver que hemos añadido una sección JSON nueva al objeto del diccionario. Lo mismo hay que hacer en el diccionario locales/es_ES.locale donde vamos a añadir la misma sección, pero con el lenguaje apropiado:

    "6":  "Sabado",
    "7":  "Domingo"
  },
  "basic.mustache": {
    "title":  "Titulo del template basico",
    "text":   "Texto que compone el template basico"
  },
  "nuevo.mustache": {
    "title":  "Título de mi nuevo template",
    "text":   "Mi nuevo template tiene este texto tan molón.",
    "another_text":   "Y este segundo párrafo explica como hacer párrafos."
  },
  "flags.mustache": {
    "change_language":  "Cambia el idioma:",
    "spanish":          "a Castellano",
    "english":          "a Ingles"
  }

Ya tenemos el template con sus idiomas listos. Ahora vamos a poner todo en su sitio para poder ver este template en un link en el template principal. Para ello modificamos templates/basic.mustache:

<div class="basic">
  <h1>{{template_title}}</h1>
  <p>{{template_text}}</p>
  <a id="new_template_link" class="clickme">{{template_new_template_link}}</a>
</div>
<div class="flags"></div>

Y en el diccionario añadimos bajo la sección de basic.mustache las entradas para new_template_link, que en nuestro caso será «Mi nuevo template» y en inglés «Mi new template».

Ahora queda la parte más cercana al Javascript, que es el indicar que cuando hagla click en el link, se muestre el nuevo template en la pantalla. Para esto, en el fichero javascripts/views/basic_view.js vamos a añadir las siguientes lineas:

BasicView.prototype.applyViewHandlers = function() {
  // Any action we want to make with this
  // template should be run here, as this
  // method is executed once the HTML code
  // is been injected in the page.

  // When clicking on the Link, the new template
  // will substitute this actual template (basic).
  var that = this;

  // Function.
  $('#new_template_link').click(function() {
    var mustache  = 'nuevo.mustache';
    var container = document.body;
    var content   = {};

    // Add the propper Locale from the locale file
    for(var i in app.locale[mustache]) {
      content['template_' + i] = app.locale[mustache][i];
    } 

    // let's clean the canvas to place
    // the new template.
    app.cleanCanvas();

    // Include the Template in the Web Page inside the
    // container we have specified.
    Templates.to_html(
      mustache,
      content,
      container,
      function() {
        that.applyViewHandlers();
      }
    );
  });

  app.views.flagsView = new FlagsView();
  app.views.flagsView.render();
};

Ya tenemos listo el template, las funciones y el texto en los diferentes idiomas. Todo esto se realizará en cliente, por lo que no tenemos por qué tener complejos servidores en Ruby, PHP o Java. Simplemente un servidor web hace las veces de servicio para estos templates. En el explorador del cliente, se cargará el diccionario del lenguaje seleccionado por el usuario, y en consecuencia los templates se rellenan con los tags adecuados.

¡Ya estamos listos para ver el contenido del nuevo template en nuestro servidor!

¿Están nuestros datos seguros?

20 May

A colación de mi post anterior, he estado investigando en el mercado a ver qué es lo que hay por ahí que realmente merezca la pena. Es decir, me he dedicado a buscar sitios web que realmente piensan en la seguridad y la privacidad de los datos.

Os puedo adelantar qu

e tampoco he visto mucho, y lo poco que he visto no tiene vistas a mejorar. Por lo pronto os puedo presentar la lista de empresas en las que ahora mismo tengo mi desconfianza depositada:

Además, he de agregar más historias sobre problemas de seguridad. A la lista se suma nuestro querido host de blogs, WordPress, que ha sufrido un ataque en toda regla en sus servicios de Automattic. NASA ha sufrido un ataque según un hacker rumano confirma. Y por último, que no último de los vulnerados, sino último de los que voy a mencionar, los servidores web de Stanford también han sido fruto de un ataque, pero esta vez de menos alcance. Sólo se han dedicado a insertar páginas web de software barato (pirata para los menos avezados).

Como podéis leer, el mundo de nuestros datos, Internet está siendo desmontado pieza por pieza. Y es que hay algunos que tienen la teoría de que esto es una señal del final del mundo, otros piensan que hay alguna industria con beneficios detrás de estos ataques. Pero al final solo podemos pensar en nuestro propio entorno y en nuestros datos.

Los datos que ponemos en las páginas web para usarlas, como Google GMail, Microsoft Hotmail, Apple Store, etc. son los mismos datos que puede usar cualquier empresa para sacar un perfil socio-demográfico de tí y cancelarte un servicio por considerarte cliente de riesgo. O los mismos que usan los hackers para usar tu ordenador como lanzadera de spam.

Así que me he propuesto hacer una lista de aquellas empresas que están en Internet y que al menos en su filosofía se preocupan por la privacidad de los datos que les doy. Aquí tenéis la reducida lista:

  • Mi Banco: Según su política de privacidad, y según las leyes, no van a vender ni usar mi información para otra cosa que no sea servirme como banco.
  • Mi Seguro médico: que su política de privacidad dice textualmente: ¨With your permission, Blue Shield may use the location information, such as GPS data, from your location-enabled product or service to provide you with information you have requested¨.
  • Mi Mujer: que dice textualmente ¨¿A quién le va a interesar que yo hable de tí o de tu vida?¨

Es impresionante ver que por ejemplo te pidan permiso para usar tu información de geo-localización. ¡Eso no lo hace ni Apple!. Y que te garanticen que no van a usar tu información para hacerte campañas de marketing como hace mi banco.

Como podéis ver, poco me queda por ahí en los que yo confíe para dar mis datos. Obviamente sigo usando servicios como GMail, o como Skype para comunicarme. Pero nunca daría un número de tarjeta de crédito por esos medios, ni menos mi dirección de casa. Imagínate la de anuncios locales que empezarían a aparecerme en mis páginas. O la cantidad de cosas que querrían venderme para curar mi obsesión por los coches. En fin, la conclusión de este post es la siguiente: ten cuidado donde metes tus datos, porque las consecuencias pueden ser peor que los beneficios.

Hay algunas empresas que empiezan a promover un movimiento que se llama ¨Host Proof Storage¨, conocido anteriormente como ¨Host Proof Hosting¨ y que algunos llaman «Host Proof Application». Del cual os hablaré más adelante cuando tenga tiempo para un post explicativo de esos con pasitos y con diagramas… Pero os dejo con la explicación básica.

Imaginar que se pudiera cifrar tus datos antes de ser enviados a Internet. De tal manera, que aquellos datos que quieres proteger, no pudieran ser abiertos por nadie más que tú y a quien le des permiso… interesante, ¿eh? Pues existe, y se hace ya. Algunas empresas ya están haciendo esto y además ganan dinero. Es decir, no ganan dinero por tener tus datos, como hacen todos los demás en Internet, sino que lo hacen por ofrecerte un servicio, sin tener la necesidad de tener tus datos en claro, es decir, analizables.

La crisis de la seguridad

16 May

Últimamente hemos estado viendo cómo las grandes tecnológicas que operan por Internet o con Internet han tenido grandes fallos de seguridad de datos. Es decir, sus sistemas de seguridad han sido vulnerados.

Por un lado tenemos a Sony, con su primer ataque reconocido, posteriormente, se descubre que no era su primer ataque, y finalmente, aquellos que somos jugadores de Play Station, tenemos que empezar a cambiar nuestros datos y dar de baja nuestras tarjetas asociadas.

Luego empezamos a oir los problemas que tiene Apple con sus móviles y la geolocalización. Nos están siguiendo a todas partes. Por lo que nos asustamos al saber que una gran corporación recopila tus datos geográficos incluso cuando no tienes tu móvil con geoposicionamiento activado. Apple por su parte, nos dice que esos datos no son para lo que pensamos, sino que lo hace ¨por nuestro bien¨.

Así pasamos al siguiente capítulo de la historia de la privacidad de los datos, descubrimos que RSA, empresa dedicada precisamente a la seguridad de los datos, ha recibido varios ataques de hackers, algunos con éxito.

Si seguimos indagando en los diferentes ataques con éxito y errores de seguridad de datos, vamos a enseñar uno todavía peor, la exposición de 3.5 millones de números de seguridad social en Texas, USA. O por ejemplo, que en la lista oficial de vulnerabilidades de alto riesgo de software, Microsoft sale más de 45 veces sobre el total de 60 listadas.

Y ahora es cuando nos pregutamos. ¿Qué está pasando?. Todos pensamos que Internet es aquella gran red donde nos podemos interconectar y todo es maravilloso. Donde la era de la privacidad se ha acabado, según nuestro amigo Mark, donde los gobiernos tienen que ser los que amenden los problemas de Google y donde puedes acceder a tu lista de búsquedas, inclusive las que usas en tu correo electrónico, aquí. Pero no nos damos cuenta que Internet solo lleva 15 años con nosotros y como toda tecnología, tenemos que aprender a usarla.

Los gobiernos están empezando a darse cuenta, y en Estados Unidos han lanzado la nueva ley de protección de la privacidad del usuario, que auna todas las preocupaciones que tenemos. Por ejemplo, va a poder forzar a las empresas a no seguir a los usuarios a través de sus servicios a menos que estos sean notificados por ello. También los usuarios pelean por su privacidad, como por ejemplo en Facebook.

El Estado de California en Estados Unidos ha lanzado una proposición de ley que hará que todas las redes sociales fuercen las opciones de privacidad en el registro del usuario nuevo y además cierre al máximo las opciones de todos los usuarios ya registrados.

Es decir, de esa red abierta donde todos estábamos conectados y felices, estamos pasando a una red de control y de limitaciones, donde de nuevo los gobiernos vuelven a tener poder.

Debemos recapacitar para saber hacia dónde queremos ir con esta tecnología, como lo hicimos con la energía nuclear cuando la descubrimos en su día. Donde no conocíamos realmente sus consecuencias hasta que pasó Chernóvil, o Hiroshima. No queremos que haya un Chernóvil en Internet, puesto que no sabemos qué consecuencias puede acarrearnos. Así que debemos ser más conscientes del uso que hacemos de la red. Tenemos que ser responsables de cómo usamos nuestros datos, y de a quién se los damos. Porque habrá veces que nunca los podamos tener de vuelta. Y otras muchas veces donde las consecuencias de haberlos dado nos seguirán durante muchos años.

Editado

He añadido la proposición de ley del estado de California al texto.

Testear Internet Explorer 7 y 8 desde tu MacOS

28 Abr

A cuantos de nosotros nos ha surgido la necesidad de tener una maquina Windows al lado para poder mirar como queda nuestra pagina en Internet Explorer. Pues aqui os dejo con un tutorial que esta basado en esta pagina web.

En primer lugar, necesitamos dos cosas básicas en nuestro Mac:

  • VirtualBox: Gestor de maquinas virtuales, que lo podeis instalar aqui.
  • Mac Ports: herramienta con la que podremos extraer el contenido que nos descarguemos de Microsoft, que os lo podeis instalar aqui.

Necesitamos VirtualBox dado que la manera oficial que nos provee Microsoft para probar las paginas en sus exploradores son imagenes completas de sus sistemas operativos, tanto Windows Vista como Windows XP.

Por otro lado, necesitamos Mac Ports para poder abrir los archivos donde residen estas imagenes de los sistemas operativos.

Una vez instalado Mac Ports, necesitamos ejecutar lo siguiente en una linea de comandos (terminal) en nuestro Mac:

$ sudo port install cabextract

Esto va a instalar el programa cabextract que necesitamos para extraer las imagenes de los EXE que nos vamos a descargar desde Microsoft.

Ahora vamos con los pasos necesarios para instalar las imagenes en nuestro Mac.

1. Descargar la imagen desde Microsoft

Aqui esta el link para descargar las imagenes que creamos convenientes:

http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&displaylang=en

No pasa nada porque sean EXE. Dado que tenemos cabextract para poder extraer lo necesario.

2. Extraer la imagen del EXE

Ejecuta lo siguiente:

$ cabextract fichero.exe

Donde fichero.exe es el fichero que nos hemos descargado.

Esto nos genera un fichero .vhd que es el que tenemos que transformar para que sea compatible con VirtualBox.

3. Transformar imagen al formato VirtualBox

Para hacerlo, tenemos que seguir ejecutando comandos en la consola, es decir, no cierres la consola todavia y ejecuta lo siguiente:

$ /Applications/Q.app/Contents/MacOS/qemu-img convert -O raw -f vpc "input.vhd" temp.bin 
$ VBoxManage convertdd temp.bin "output.vdi" 
$ rm temp.bin 
$ mv "output.vdi" ~/Library/VirtualBox/VDI/ 
$ VBoxManage modifyvdi "output.vdi" compact

Ahora ya tenemos la imagen preparada en VirtualBox para ser inicializada.

4. Iniciar la imagen desde VirtualBox

Abrimos VirtualBox desde Aplicaciones en nuestro Mac. Y vamos a crear una imagen nueva:

Hacemos click en new

E iniciamos el proceso de creación de imagen

Escogemos un nombre y el tipo de imagen. En nuestro caso hemos descargado la imagen de Windows XP con IE7 instalado.

E incorporamos la RAM que queremos dedicar a la maquina. En este caso le vamos a dar 512MB de RAM. Suficiente para lo que queremos de la maquina.

Incorporamos el disco virtual que hemos creado anteriormente en el paso 3 dentro de la imagen. Para ello, hacemos click en «Use Existing hard disk» y luego en el icono que aparece a la derecha de la selección.

Y buscamos nuestra imagen dentro del directorio donde la hemos dejado (el fichero VDI que hemos generado).

Ya tenemos la imagen preparada para ser iniciada y usada.

Tan solo tenemos que seleccionar la imagen de la lista de maquinas virtuales, y hacer click en start en el menu de VirtualBox. La maquina aparecera automaticamente como una ventana en nuestro escritorio.

De esta forma podremos probar nuestras paginas en Microsoft Internet Explorer 6, 7 y 8 de manera legal, dado que Microsoft provee estas imagenes precisamente para este proposito, y ademas de manera sencilla. Una vez que tienes una imagen, el resto es muy facil.

Chrome OS revelado

30 Oct

Por fin he conseguido poner las manos encima de un ChromeOS. Finalmente, despues de descargarme el codigo, compilarlo, y crear una imagen, he conseguido iniciar una maquina virtual con KVM. Pantallas a continuacion!

Pantalla de entrada:

 

Llegada al «inicio»:

 

Opciones del sistema:

 

Listado de archivos (ejemplo de /home/chronos):

 

Si queremos acceder a la consola de comandos propia (crosh) hay que pulsar Ctrl + Alt + T:

 

Si escribimos help obtenemos los comandos necesarios, entre ellos «shell»:

 

que nos lleva a la consola de Linux (finalmente!):

 

Y podemos ver que hay detras de ChromeOS:

 

Proximamente publicare un post sobre como compilar ChromeOS e iniciar una imagen con KVM.

Redmine Task Manager – renovado

29 Oct

En mi afan por mejorar el gestor de tareas de Redmine, he subido nuevo codigo al repositorio. Como vereis, las mejoras son mas bien esteticas, para que sea mas sencillo trabajar:

 

 

 

 

Espero que os guste!

 

«Anonymous Content» en Google Chrome

30 Sep

Todos los que hemos creado alguna vez una extension para Firefox sabemos que existen varias formas de representar ventanas dentro del explorador. Una de ellas, la recomendada por el equipo de Mozilla es usando su protocolo XUL para representación de interfaces con el usuario. Por otro lado, existe también la posibilidad de insertar nodos dentro del DOM del documento por medio del «Anonymous Content». De esta forma, podemos representar HTML al usuario que la página no puede ver ni acceder a él.

Por otro lado, si quisiéramos hacer lo mismo en Google Chrome, nos encontraríamos con el problema de que este explorador no cuenta ni con un API del estilo de XUL, ni tampoco con la manera de introducir nodos en el árbol DOM sin que sean vistos por la página en la que los introducimos.

éxtasis ácido camión

Existe de todas formas, una manera de poder resolver este problema en Google Chrome. He escrito un articulo en el que explico la manera más sencilla de hacerlo, y cómo podemos proteger nuestro contenido de la pagina en la que lo introducimos. Por medio de IFRAMES. He aquí el articulo:

http://www.borderstylo.com/posts/220-anonymous-content-injection-in-google-chrome

Con esta explicación podrás introducir contenido protegido sin el temor de que la pagina pueda extraerlo o modificarlo.

Conectarse a varios esclavos de MySQL con Ruby

15 Sep

Vamos a ver como nos conectamos a varios esclavos de MySQL que replican de un maestro. Como comentamos en el capitulo anterior, la replicación  de MySQL nos permite aumentar la capacidad de lecturas de nuestra base de datos.

Ahora vamos a estudiar la manera en la que podemos conectar nuestro programa de Ruby a todos esos esclavos. La mayoría de las gemas que nos encontramos soportan múltiples esclavos. Pero la manera en la que se conectan es muy simple, y si nos encontramos en una situación de mucha carga, podemos llegar a tumbar toda la base de datos. Veamos el ejemplo de la gema Sequel.

Para configurar múltiples esclavos, tenemos que configurarla de la siguiente manera (codigo ejemplo de su documentación):

DB=Sequel.connect('mysql://master_server/database', \
    :servers=>{:read_only=>proc{|db| {:host=>db.get_slave_host}}})
  def DB.get_slave_host
    @current_host ||= -1
    "slave_server#{(@current_host+=1)%4}"
  end

Siendo master_server nuestro servidor maestro y slave_server#{(@current_host+=1)%4} nuestros esclavos.

Vamos a hacerlo más aleatorio:

DB=Sequel.connect('mysql://maestro/my_db', \
    :servers=>{:read_only=>proc{|db| {:host=>db.get_slave_host}}})

  def DB.get_slave_host
    slaves = [
      "esclavo_1",
      "esclavo_2",
      "esclavo_3",
      "esclavo_4",
      "esclavo_5",
      "esclavo_6"
    ]
    return slaves[rand(slaves.length - 1)]
  end

Ahora bien, viendo este código, podemos ver ya que la distribución de las conexiones va a ser equitativa, es decir, si tenemos 4 esclavos, cada uno de ellos va a recibir el mismo número de conexiones. Esto en un mundo ideal nos viene bien, pero no nos viene tan bien cuando tengamos alguno de los esclavos con más carga que los demás…

Vamos a darle una vuelta de tuerca. Vamos a tratar de comprobar el estado de los servidores antes de conectarnos, para saber si realmente queremos conectarnos a dicho servidor, o no…

DB=Sequel.connect("mysql://maestro/#{db_name}", \
    :servers=>{:read_only=>proc{|db| {:host=>db.get_slave_host}}})

  def DB.slaves_array
    slaves = [
      "esclavo_1",
      "esclavo_2",
      "esclavo_3",
      "esclavo_4",
      "esclavo_5",
      "esclavo_6"
    ]
    return slaves
  end

  def DB.get_slave_host
    tries = 0
    while tries <= DB.slaves_array.length
      slave = DB.get_slaves_array[rand(DB.get_slaves_array.length - 1)]
      return slave if DB.get_slave_delay <= 1
      tries += 1
    end
  end

  def DB.get_slave_delay(slave, db_name)
    begin
      DBSlave=Sequel.connect("mysql://#{slave}/#{db_name}")
      delay = DBSlave["SHOW SLAVE STATUS"]
      return delay[32].to_i
    rescue
      return 1000
    end
  end

Parte por parte.

Lo que este código hace es simplemente  comprobar si el esclavo al que nos vamos a conectar esta sin retrasos con respecto al maestro y ademas si nos podemos conectar. Para ello, cuando Sequel llame a db.get_slave_host lo que vamos a hacer es lo siguiente:

def DB.get_slave_host
    tries = 0
    while tries <= DB.slaves_array.length
      slave = DB.get_slaves_array[rand(DB.get_slaves_array.length - 1)]
      return slave if DB.get_slave_delay <= 1
      tries += 1
    end
  end

Vamos a sacar un esclavo de la lista de manera aleatoria:

slave = DB.get_slaves_array[rand(DB.get_slaves_array.length - 1)]

Y posteriormente vamos a tratar de conectarnos al esclavo y mirar su estado:

return slave if DB.get_slave_delay <= 1

Esto llama a la función que hemos definido:

def DB.get_slave_delay(slave, db_name)
    begin
      DBSlave=Sequel.connect("mysql://#{slave}/#{db_name}")
      delay = DBSlave["SHOW SLAVE STATUS"]
      return delay[32].to_i
    rescue
      return 1000
    end
  end

Esta función va a comprobar el estado del servidor. Si el esclavo tuviera algún problema, devolvería un retraso elevado (cuando los esclavos tienen mucha carga, suelen retrasarse con respecto a su maestro) o si no podemos conectar, entonces devolverá 1000, dando así un retraso muy elevado indicando que el servidor no esta disponible.

Nota: para que nuestro código pueda preguntar por el estado de los esclavos («SHOW SLAVE STATUS») necesitamos dar privilegios SUPER, REPLICATION CLIENT al usuario que hemos designado a nuestro programa para conectarse a los esclavos:

mysql> GRANT SUPER, REPLICATION CLIENT ON *.* TO 'user'@'domain' IDENTIFIED BY 'password'

En conclusión, si queremos que nuestro código soporte varios servidores esclavos y que compruebe la carga antes de cada conexión, debemos complicar la lógica de conexión a la hora de conectarnos a la base de datos. Las gemas como Sequel nos pueden ayudar a ello con abstracciones de conexión. Es muy sencillo hacer esta comprobación cada vez que nos conectamos. Pero como en todo, este método de comprobación no es escalable a grandes sistemas dado que cada vez que vamos a realizar una lectura, primero hacemos una conexión al esclavo para mirar su estado. Esto hace que la cantidad de conexiones se multiplique por dos.
Mi recomendación es que se trate de hacer un método híbrido donde en paralelo a este código, se compruebe el estado de los esclavos cada vez, y se modifiquen los pesos de cada esclavo dependiendo de dichas comprobaciones. Pero esto corresponde al siguiente post…