viernes, 24 de mayo de 2013

De Bill Gates, y el Nacimiento del Software Privativo

Bill Gates de Joven
Ahorita que estoy leyendo la biografía de steve jobs, me encontré con un pasaje muy interesante que me gustaría compartir:

Allá por los 60's, cuando la informática personal apenas iba tomando forma, los geeks de aquellas épocas se reunían en garages a compartir ideas, noticias y avances tecnológicos entre ellos. Steve Jobs y Steve Wozniak eran atendientes a uno de estos clubes geek, donde se permitía el fácil (y libre) acceso a la tecnología a las personas interesadas.

La cosa es, que los componentes y kits eran muy caros, entonces no estaban al alcance de todos. Cuando el primer kit de lo que podríamos llamar "el precursor del ordenador personal" salió a la venta (El Altair), no tomó mucho tiempo antes de que el club a donde asistían los 2 steves a estas "quedadas" se hiciera con uno. La idea era que si alguien se podía hacer con una pieza o cosa interesante, montaba una presentación que ofrecía gratuitamente para todos los asistentes, de manera que todos se nutrían con conocimiento. La filosofía de ese tipo de clubes era al hardware lo que la filosofía del software libre tal y como la conocemos ahora es para los programas. El propósito central de todo era COMPARTIR, para nada Comercializar.

Sucede que en el club a donde asistían los steves no sólo llegó a aparecerse este kit para el disfrute y estudio de todos los curiosos, sino que también llegaron copias de la versión de BASIC que Bill Gates diseñó para el Altair (Esta es, la precursora de lo que se convertiría en Windows más adelante). Bill Gates no era fanático de la filosofía "hippie" enfocada a compartir conocimiento en estos clubes, y tras enterarse de que las copias de su software llegaron a manos del club a donde asistían los steves, y que la gente estaba compartíendolas entre ellos sin pagar, escribió una carta al club que rezaba:

Cito del libro:

Como la mayoría de los aficionados a la electrónica ya sabrán, casi todos ustedes se roban el software. ¿Es esto justo? [...] Una de las cosas que están consiguiendo es evitar que se escriba buen software. ¿Quién puede permitirse realizar un trabajo profesional a cambio de nada? [...] Agradeceré que me escriban todos aquellos que estén dispuestos a pagar.

Esto es lo que (si no me equivoco), podríamos considerar el nacimiento de la mentalidad detrás software privativo, o al menos su representación más pura con el ejemplo del software privativo más famoso de la historia: Microsoft Windows. ¿Interesante no?

martes, 21 de mayo de 2013

[Concurso] Gana con Xenode (Facebook)


Es un placer para mí anunciarles hoy el inicio de nuestra serie de concursos "Gana con Xenode". Estos concursos se llevarán a cabo por medio de nuestra página de facebook y se darán diferentes premios. Se puede participar desde cualquier país, sin importar la edad y el envío de los premios no tendrá costo para los ganadores. A continuación un video explicativo de los concursos:


Si aún no nos sigues en Facebook, este sería un buen momento para Hacerte Fan:


domingo, 19 de mayo de 2013

#Snippets: Enumerar records individualmente en las views de Rails


Esta es una técnica útil que me saqué de la manga para ennumerar records  individualmente en las vistas de Rails, srive para mostrar algo así como "Record #1, Record #2, Record #3" etc. en la vista show (o bien, cualquiera) de un record individual de la base de datos en Rails. Mi ORM es Mongoid (en la app donde probé esto)  pero supongo que funciona para cualquier tipo de ORM usando el mismo snippet, no tendría porqué no funcionar (aunque me parece que usando DB's relacionales hay alternativas más elegantes a esta para lograr el mismo objetivo) Veamos entonces el ejemplo:

<% current_id = @object.id
   Mymodel.all.each_with_index do |indexed_object, i|
   if indexed_object.id.to_s == current_id.to_s %>

  <h1>Object #<%= "#{i.to_i + 1}" %></h1>

<% end %>
<% end %>

Creo que el snippet habla por si solo, pero por si no, lo explico:

Primero obtenemos el ID del objeto "actual", (del que queremos obtener su ennumerador) y lo guardamos en una variable llamada "current_id". corremos el loop ennumerador y le pasamos un condicional para que cuando llegue el momento en que se tope con el id del objeto en cuestión añada el número correspondiente a dicho objeto en nuestro H1 que reza algo como "Object #X" (Reemplazando esa X por el número). Nótese que convertimos el índice (variable "i") a número íntegro con el método "to_i" (lo mismo da que la variable se llamase "i" o "index", igual usaríamos to_i no se confundan por las 2 "i") y le sumamos 1, ¿Porqué? Bueno, porque el ennumerador en un array de ruby empieza en 0 y no queremos tener algo como "Venta #0" en nuestra vista generalmente.

viernes, 17 de mayo de 2013

Cuentas de correo "@midominio" Gratis: Adiós Google Apps


Como se debieron haber enterado hace ya algún tiempo, Google empezó a cobrar por el uso de Google Apps. El mínimo son 5 dólares por usuario al mes y si bien Google Apps y toda su infraestructura es buena hasta cierto punto, la realidad es que la mayoría de las personas con pequeños negocios lo usaban para obtener cuentas de correo personalizadas del estilo "@midominio.TLD" Dejando del lado cualquier otra feature que pudiesen ofrecer.

La alternativa gratuita de Google Apps era eficaz para este caso de uso con un total de hasta 10 cuentas de correo personalizado gratis por dominio, Ahora que esta opción es de pago (y a mi parecer algo cara) es difícil encontrar una alternativa similar que nos preste estos beneficios sin pagar, pero por suerte existe y viene de la mano de Microsoft y Outlook.com ofreciéndonos no 10, sino 50 direcciones de correo personalizado completamente GRATIS.

Veamos pues cómo obtenerlas:

NOTA: Para poder hacer esto requerirás tener un dominio comprado con cualquier compañía registrante de dominios y acceso a su DNS Manager para crear nuevos records (en este caso uno MX), además de una cuenta microsoft cualquiera para poder acceder al panel administrativo de tu dominio en Live.

Paso 1:

Tenemos que irnos a http://domains.live.com/ para asociar un dominio a nuestro panel live. Iniciamos sesión con la cuenta microsoft que tengamos y damos click en el link de "Introducción" de Dominios Personalizados como se alcanza a apreciar en la imagen a continuación:


Paso 2:

Una vez clickeamos ahí (con nuestra sesión iniciada) seremos llevados a una pantalla donde tendremos que escribir la dirección de nuestro dominio (puede ser cualquier TLD sin problemas) y dejamos marcada la opción de "Configurar Outlook.com para mi dominio" como se muestra en la siguiente imagen:


Damos click en "Continuar" y en la siguiente ventana metemos el captcha que nos piden y pulsamos "Aceptar". Luego de varios intentos por introducir el captcha correcto (jajajjaa) deberíamos ver algo como esto:


Ahí nos explican qué datos debe llevar el registro MX que debemos crear en nuestra consola de administración del dominio. En este tutorial usaré Godaddy como referencia:

Sin cerrar la página previa, abrimos godaddy.com en nuestro navegador y nos logueamos. Accedemos a "Mi Cuenta > Dominios"  y hacemos click en el botón verde de Iniciar. Nos aparecerá algo como esto:


Seleccionamos el dominio para el cual queremos activar el correo y damos click en su enlace, lo que nos llevará a una pantalla parecida a esta:



Donde le daremos click a la algo oculta (pero presente) opción para lanzar el DNS Manager del dominio, cosa que a su vez nos traerá a otra ventana donde podremos añadir registros DNS para el dominio en cuestión. En este caso nos interesa la sección de MX, así que la buscamos y le damos click en "Agregar rápidamente" para luego introducir los datos que Microsoft nos entregó capturas atrás:


Nos vamos hasta abajo y clickeamos el botón de "Guardar archivo de zona". Tras haber guardado el registro DNS correctamente, esperamos unos minutos (puede tardar hasta 1 hora y en casos exagerados incluso 48) y regresamos a la página de verificación de Microsoft (la que no cerramos al abrir godaddy), donde si clickeamos el botón de "Actualizar" en el recuadro amarillo veremos que nuestro dominio fue verificado exitosamente y ahora solo nos queda añadir las cuentas personalizadas que queramos, (hasta 50 por dominio, recuérdenlo). En caso de haber agregado el registro y que tu dominio no se verifique al clickear el "actualizar" en la página de verificación, trata de nuevo 1 hora 15 minutos más tarde, y si no queda, vuelve intentar 24 o hasta 48 horas después.

Paso 3:

Ya que el dominio esté verificado con Microsoft, en la siguiente pantalla que aparecerá podremos añadir nuestras cuentas personalizadas clickeando el botón de "Añadir" que vemos en la imagen de abajo:


Ya que hayamos creado las cuentas que queramos, para acceder a ellas nos vamos a Outlook.com donde podremos usar nuestras recién creadas credenciales personalizadas para acceder a nuestra bandeja de correo personal. los correos que mandemos serán enviados por medio de una dirección del tipo @midominio y también nos podrán escribir a la misma sin ningún problema, pudiendo nosotros checar el correo en Outlook.com (o cualquier cliente de correo o dispositivo que queramos usar) de manera completamente normal; Recordemos que esta dirección de correo tiene las mismas prestaciones y comportamiento de una cuenta microsoft normal, pero con nuestro propio dominio después del arroba.

jueves, 16 de mayo de 2013

#Snippets: Generador de strings aleatorios en Ruby


Últimamente me he topado con más de un caso en el que tengo que hacer un generador de claves aleatorias (strings que contengan números y letras random) con cierto número de caracteres. ¿Para qué nos serviría dicho generador?


  • Generar contraseñas volátiles aleatorias para el usuario
  • Generador de claves WEP/WPA para proteger Wi-Fi
  • Generar una "uniclave" para algún sistema de registro de productos

Y sin duda para más...

Bueno, este es el snippet que yo armé y uso en estos casos. Se trata de un pequeño método/función que lo que hace es formar 2 arrays, uno con las letras de la A a la Z y otro con los dígitos del 0 al 9 y nos devuelve una string que resulta ser la combinación aleatoria de las letras y números antes mencionados cada que corre, haciendo una nueva combinación de 8 caracteres cada vez:

  def random_string
    a = ("a".."z") 
    b = (0..9)
    c = a.to_a + b.to_a
    key = c.shuffle[0,8].join
  end

Cabe destacar que se pueden hacer combinaciones con todo tipo de caracteres y que nos devuelvan strings tan largos como necesitemos modificando tan solo un poquito el método.

#IO13: Soporte oficial para PHP en App Engine


Hace rato estaba revisando la "keynote list" para el Google I/O de este año y de las disponibles sólo unas pocas me llamaron la atención, en especial una llamada "A new language for App Engine". Me metí a su resumen y según vi los de Google decían que se trataría de la adición de soporte para un nuevo lenguaje muy solicitado por parte de la comunidad de GAE. Me emocioné y pensé: "¡Al fin!, Ruby!" pero tras investigar un poco resulta ser que alguien en reddit ya dio con la respuesta a tan anhelada pregunta (¿Cuál lenguaje será?) y la respuesta resultó ser: PHP:


Así es. Al parecer por el código del trunk de AppEngine tendremos a PHP como siguiente lenguaje soportado en la PaaS de Google. Interesante, para algunos incluso emocionante, pero no para mí. No me gusta tanto PHP, lo considero incluso un lenguaje muerto. Me hubiera gustado ver a Ruby en GAE :/ Desgraciadamente no siempre se tiene lo que se quiere... ¿O sí? Puede ser que en el último minuto los de Google nos sorprendan con algo así como: "Y no eran uno, eran dos! denle la bienvenida a Ruby en GAE!" (Soñar no cuesta nada) jeje.

miércoles, 15 de mayo de 2013

[QuickTip] Atributos predeterminados en Mongoid Rails


Antes que nada una disculpa por la inactividad en el blog y las redes sociales, hemos estado demasiado ocupados (sobre todo yo) Pero acá seguimos. Aquí un quicktip:

Fíjense que estoy construyendo una plataforma web para una agencia de viajes y estamos manejando algo así como un "monedero electrónico" el cual lo que permite es que cada que un usuario de la aplicación compre algo ésta le regrese en "puntos" de un 5% al 100% del total de su compra y más tarde los pueda usar para comprar otras cosas dentro de la misma plataforma. Hacer esto requiere inicializar un usuario con un monedero electrónico en ceros, pero al hacerlo con un callback el resultado que obtuve fue un "true" en lugar de un cero, cosa que no servía de nada pues el usuario debe ver cómo su monedero empieza en ceros y se le va sumando dinero poco a poco (hay una vista para eso, y si en el programa decía "true" el usuario no entendería); Para lograr el resultado esperado, simplemente tuve que cambiar el approach de callback por uno más sencillo: Atributos predeterminados. Si usas Mongoid como tu ORM, entonces ésta es la manera correcta de hacerlo. En el modelo:


Simplemente ponemos una coma después de declarar el atributo y con la declaración del "default" y un hash con el valor que queremos que sea el predeterminado lograremos nuestro cometido. En mi ejemplo estoy siendo excesivamente "verboso" pero espero que para fines del post se entienda porqué. Lo mismo daba poner "0" a todo ese barullo en mi hash, pero mejor explícito que "abierto a la interpretación". Establecer atributos predeterminados como lo muestro en mi línea de código allá arriba permitirá que dicho atributo se "setée" al momento de la creación del objeto, de manera que cada objeto nuevo de un modelo determinado que incluya este tipo de setup se inicializará con el valor deseado predeterminado automáticamente en la base de datos al momento de su creación.

lunes, 22 de abril de 2013

[QuickTip] Paginación en Rails 3 y Mongoid


Así que tienes una RailsApp con Mongoid que tiene muchísimos records en la base de datos y quieres mostrarlos todos al público de una manera eficiente, ordenada y no abrumadora... ¡Necesitas paginación! En Rails tenemos 3 principales maneras rápidas de lograr implementar paginación en una app: Con Ajax, con la gema Kaminari o con will_paginate.

En este post les hablaré de la última opción, que es la que yo he usado con Mongoid y me ha resultado bastante eficiente, aunque su configuración difiere un poco de la versión para ActiveRecord. Veamos pues cómo integrarla:

1) Añade la gema

Nos vamos a nuestro Gemfile y añadimos:

gem 'will_paginate', '~> 3.0'

Hacemos bundle install y luego proseguimos con:

2) Requerirla en la aplicación

Esto se hace añadiendo las siguientes líneas a tu archivo config/application.rb:

require 'will_paginate'
require 'will_paginate/array'

3) Paginar en el controlador

Por ejemplo, si yo quiero paginar mi acción Index del controlador que por default muestra todos los records de un determinado objeto de la base de datos en su vista, haría algo como:



En este caso estaría paginando en mi acción Index del controlador todos los objetos de "CallBundle" mostrando 10 resultados por página que el usuario pase con su selector (osea picándole al numerito 1-2-3-4 etc).

4) Activarlo en la vista

Ahora si quiero tener paginación en dicha vista index, le añado:

<%= will_paginate @call_bundles %>

Donde @call_bundles es el objeto a paginar que elegí en el controlador.

Y eso es todo! estamos paginando en nuestra app rails con backend mongoid, ahora solo queda (si queremos) pasarle algo de CSS a ese paginador y listo.

viernes, 19 de abril de 2013

Markdown WYSIWYG en tu aplicación Rails


Ahorita estoy construyendo una aplicación Rails para una agencia de viajes que resulta ser cliente nuestro. La idea que hay detrás de lo que el cliente quiere es muy buena y es un proyecto que me emociona trabajar. Una de las características que estoy implementando y añadiendo ahorita es la posibilidad de generar contenido con formato desde el submit de un formulario directamente. En cuanto supe que teníamos esa necesidad inmediatamente pensé en Markdown, una cosa ligera, práctica y poderosa para estos casos.

El markdown es un formato de texto estilizado que se basa en ciertas reglas para aplicar estilos, sin ser una edición de texto con etiquetas HTML directamente como la encontrada en los editores de Blogger o Wordpress por ejemplo. La implementación de markdown se puede hacer sin necesidad de un editor, tu le das capacidades de interpretación de Markdown a tu app y listo, si los usuarios escriben markdown en sus formularios, ya en las vistas quedará interpretado y con formato. Sin embargo yo quiero que esta app sea lo más noob-friendly posible, así que añadiré un editor WYSIWYG para markdown (después de implementarlo en la app) e igual un corrector ortográfico, veamos cómo lograrlo:

1) RedCarpet

Primero le dí capacidades de interpretación de Markdown a mi app, esto se logra de la siguiente manera:

Añadir RedCarpet a tu Gemfile

gem 'redcarpet'

Luego hacemos bundle install y proseguimos creando un helper method que nos permita renderizar el contenido de una form que se envió con markdown en la vista indicada de la aplicación ya con el formato renderizado. El código de este método va en helpers/application_helper.rb y será el siguiente:


module ApplicationHelper

  def markdown(text)
    renderer = Redcarpet::Render::HTML.new(:no_links => true, :hard_wrap => true)
    options = {
      autolink: true,
      no_intra_emphasis: true,
      fenced_code_blocks: true,
      lax_html_blocks: true,
      strikethrough: true,
      superscript: true
    }
    Redcarpet::Markdown.new(renderer, options).render(text).html_safe
  end

end

Con esto ya puedo llamar en mi vista al campo formateado usando este método y renderizará correctamente con algo como:

<%= markdown @objeto.campo %>

Aunque esto bastaría para renderizar el markdown que haya sido escrito en un form, no toda la gente sabe markdown y dar un curso intensivo de cómo escribir esto a cada empleado de la agencia es tedioso, así que les ayudaremos un poquito con un lindo editor WYSIWYG en el siguiente paso.

2) Una GUI para las TextAreas

Podemos integrar varias opciones para lograr esto, ya que lo haríamos en el lado del cliente con javascript y eso quiere decir que tenemos TONELADAS de opciones para usar jajajajaja. Sin embargo, en mi caso personal tras hacer varias pruebas, me quedo con MarkitUp! un pequeño y confiable editor muy fácil de implementar y usar, veamos cómo:

Primero nos bajamos el dichoso editor (ya preparado para Markdown y ser ligero) desde acá. Una vez descargado lo extraemos y copiamos la carpeta resultante en nuestro directorio public/assets de la aplicación.

Referenciamos los archivos de la siguiente manera en la aplicación:

<!-- markItUp! skin -->
<link rel="stylesheet" type="text/css" href="/assets/markitup/skins/markitup/style.css">
<!--  markItUp! toolbar skin -->
<link rel="stylesheet" type="text/css" href="/assets/markitup/sets/markdown/style.css">
<!-- markItUp! -->
<script type="text/javascript" src="/assets/markitup/jquery.markitup.js"></script>
<!-- markItUp! toolbar settings -->
<script type="text/javascript" src="/assets/markitup/sets/markdown/set.js"></script>

Y luego simplemente en nuestra form donde vayamos a usar el editor debemos darle la clase indicada a las textareas que queremos formatear con markdown de la siguiente manera:

<%= f.text_area :description, :class => 'markItUp' %>

Una vez hecho esto, añadimos al final de nuestra form el script de markitUp también, que es el siguiente:

<script type="text/javascript" >
   $(document).ready(function() {
      $(".markItUp").markItUp(mySettings);
   });
</script>

Y con eso, dichas textareas del formulario cargarán directamente con MarkitUp para poder disfrrutar de los beneficios del Markdown en nuestra app.

jueves, 18 de abril de 2013

[HowTo] Deploy Gratuito de Rails + Mongoid en Heroku


Trabajar con Rails y Mongoid es la combinación ganadora si quieres ser productivo y además divertirte mientras programas. Hace tiempo les hablé de cómo subir una aplicación rails de esas que ocupan tablas SQL al famoso servicio de hosting para webapps Heroku. El día de hoy aprenderemos cómo hacerlo si quieres utilizar Mongoid (¡Backend de MongoDB en nuestra app!), y de paso les hablaré del Heroku Toolbelt:

1) Heroku Toolbelt

Resulta que la gema "heroku" para Rails ya no está soportada y en lugar de estar segregando las herramientas de la plataforma en varios esfuerzos diferentes ahora el Heroku Team ha decidido hacer una "unisolución", conocida como el "Heroku Toolbelt".

Si queremos subir nuestra app a heroku, (sea la que sea) ocuparemos instalarnos esta utilidad (y quitar la gema heroku de la misma si la ocupábamos). Instalarlo es bastante sencillo a decir verdad y es un proceso prácticamente automático y multiplataforma, aquí les explicaré cómo instalarlo de forma genérica, especialmente enfocado a sistemas linux (excluyendo Ubuntu, pues con esta distro tenemos otro método); Corremos el siguiente comando:

wget -qO- https://toolbelt.heroku.com/install.sh | sh



Y luego añadimos lo siguiente a nuestro ".bashrc" (archivo oculto dentro de nuestra carpeta personal):

PATH="/usr/local/heroku/bin:$PATH"

Finalmente, cerramos y abrimos la consola (la reiniciamos pues); Una vez hecho esto lo tenemos instalado. Configuramos nuestras claves SSH con su servidor y listo.

2) Preparando el entorno

Primero y antes que nada, bájate la más nueva versión de bundler así:

gem install bundler --pre

Luego, dile a tu gemfile explícitamente que use ruby 1.9.3 así:


Ya que estemos usando explícitamente ruby 1.9.3 en el Gemfile, corremos:


1
2
3
4
5
6
7
bundle install
git init 
git add .
git commit -m "Heroku ready"
heroku login
heroku create myapp
heroku addons:add mongohq:small

Y eso hará el bundle de las gemas, inicializará un repo git dentro de la app (Que en este caso tiene de nombre "myapp") y añadirá todo el código hasta donde vamos para luego crear una "instancia de app" de heroku y finalmente instalar la extensión que nos va a permitir usar MongoDB dentro de heroku como nuestra base de datos; Cabe destacar que el uso de esta extensión requiere de una cuenta verificada de heroku (con una tarjeta de crédito asociada) y el comando 6 inicializa la add-on en la versión Small de la base de datos proveída por MongoHQ, cosa que quizá quieras cambiar según la envergadura del proyecto.

Links útiles en esta parte:


3) Configuración y Deploy

Una vez tengamos el paso de arriba configurado y listo, proseguimos añadiendo a nuestro archivo config/mongoid.yml algo como:


production:
  sessions:
    default:
      uri: <%= ENV['MONGOHQ_URL'] %>
      options:
        skip_version_check: true
        safe: true

Guardamos y corremos los siguientes comandos:


1
2
rake assets:precompile
rails s -e production

Si salen errores, vemos el log de la consola y los corregimos. Abrimos nuestro navegador en el http://localhost:3000 habitual de rails y checamos que todo funcione como se espera... Recordemos que si teníamos records en la base de datos que usábamos para development y estos no están en la de producción es posible que las cosas fallen, hagan su dump de mongo primero antes de hacer el deploy y luego (ya con la app arriba) hagan el restore para evitar esto una vez colgados en heroku.

NOTA: Ocuparás tu URI de acceso MongoHQ para sacar datos como tu usuario, contraseña y servidor en caso de hacer el proceso de dump/restore ya en la nube. Estos datos se obtienen con el comando heroku config.

Finalmente con el comando:

git push heroku master

subimos todo a heroku y abrimos la aplicación con heroku open. Si todo está bien, hemos terminado! y si no, tendremos que revisar nuestros logs con heroku logs y tras corregir errores, reiniciar el servidor con heroku restart.

lunes, 15 de abril de 2013

Paypal y Rails: ¿Cómo cobrar desde tu aplicación web? [ESPECIAL]


NOTAS: Yo uso MongoDB como mi base de datos, entonces este tutorial está hecho asumiendo que tu backend es Mongoid y no ActiveRecord, por ejemplo aquí no verás migraciones. También es importante aclarar que en el caso de este post "card_bundle" es lo que vendemos y "card_bundle_sale" es nuestro "carrito" u "orden"

Este es un tutorial especial que voy a escribir mientras estoy programando una webapp para un cliente ya que considero que este es uno de los temas que generan más dudas entre los desarrolladores web allá afuera. Paypal puede ser intimidante, ¡Díganmelo a mi! Así que vamos paso por paso juntos:

NOTA: Aquí no enseñaré cómo implementar una aplicación de compra-venta en Rails, ya que esta es una cuestión genérica que no se puede aglomerar en un solo tutorial para todos los casos. El propósito de este tutorial más bien es entregar un método lo más flexible posible para que cualquiera que esté construyendo una app de e-commerce según su caso aplicado allá afuera pueda integrar cobros por Paypal en su aplicación web sin depender de un diseño o workflow previamente fijado.

So, tienes una aplicación Rails donde quieres de hecho cobrar dinero. En mi caso estoy construyendo una plataforma para ventas de viajes estilo BestDay para una agencia de reciente comienzo y la idea es poder vender directamente algunos paquetes desde la página web a las personas usando sus tarjetas de crédito. El workflow "más básico" de un sitio de e-commerce es el siguiente:

Ente a vender => Órdenes => Objeto de Venta (Carrito)

Por ejemplo, una aplicación donde se vendan playeras, la gente pueda elegir las que le gusten seleccionándolas con un checkbox (armando en el background un objeto de "orden") y finalmente se les muestra "un carrito" u objeto de venta que se utilizará como "la cuenta" del pedido. Los datos de este último son los que debemos pasarle a paypal, veamos cómo, paso por paso:

1) Crea 2 cuentas en la sandbox de Paypal

Necesitaremos una de vendedor y una de comprador, a ambas podemos ponerles el dinero "de mentiras" que queramos y otros atributos que consideremos necesarios. Las podemos crear en Paypal Developers en el apartado de Applications > Sanbox Test Accounts. Una vez creadas podemos acceder a ellas desde el Paypal Sandbox para hacer las pruebas y corroboraciones pertinentes.


2) Website Payments Standard

Vamos a integrar Paypal al checkout de nuestro carrito en la aplicación Rails, la manera más fácil sería por medio de Website Payments Standard y por ahí comenzaremos. So, en mi app yo tengo una sección donde la persona puede escoger de una lista de varios items y darles una cantidad a cada uno para comprar más de uno de ese item. Lo que quiero hacer es que cada que alguien termine de armar una orden se le lleve a pagar esa orden con Paypal inmediatamente, ¿Cómo se hace?


Ciertamente no es difícil, en mi caso específico yo vendo un ente llamado "card_bundle" por medio de "card_bundle_sales" (órdenes, si quieres llamarlo así) y guardo el proceso de venta en la base de datos a manera de "sales" para tener una especie de registro de ventas hechas automáticamente. En mi caso lo que hice fue dejar un botón de submit normal en la parte de la aplicación donde la gente compra (obviamente sin diseño ni nada allá arriba) que al ser pulsado crea una venta nueva en mi registro de sales y por tanto popula un registro de "card_bundle_sale" que puedo utilizar para pasarle las variables adecuadas a paypal con respecto a la orden. Veamos el código usado para lograr esto:

Controlador Sales:


De aquí nos interesa lo que aparece en la línea 29, básicamente le estoy diciendo al controlador que si una nueva venta se crea redireccione al usuario a la "paypal_url" especificando como argumento la URL de retorno que quiero para cuando la compra está completada (dentro del paréntesis).

Modelo CardBundleSale

Para definir esa "Paypal URL" ocupo hacerlo en el modelo de mi ente que represente "una orden" en el sistema, en este caso es CardBundleSale. el código para ese método queda más o menos así:



Aquí es donde la cosa se puede poner "intimidante" pues hay que checar la documentación de paypal, verán: El método que ven ahí arriba no hace otra cosa más que crear una URL de Paypal que podemos usar para cobrar. Daría lo mismo si esta data se le alimenta a Paypal por este método o bien, si usáramos un botón embedido nadamás, la data sería la misma. Cabe destacar que los valores en azul son valores que en mi opinión se deben pasar en cualquier caso, son "los de cajón" (por cierto, cmd siempre ha de estar definido como '_xclick' para que la cosa funcione) Mientras que el método que itera sobre el array de items que estoy vendiendo es código muy específico para mi aplicación, tu tendrías que crear tu propio método iterante según el caso específico de tu escenario. A final de cuentas construimos nuestra URL y listo!

Vista CardBundles#Index

Por acá sólo tenemos el submit y ya:


Como verán, nada de otro mundo en esta vista, creamos nuestro objeto "venta" (que a su vez popula una "orden" o "card_bundle_sale" y listo.

Con este "arreglo" ya podemos empezar a vender desde nuestra app, Genial! Hagamos una prueba:



Como verán, el pago procesa y todo, ¡Yay! pero aún no podemos cantar victoria...

3) IPN

Con las 3 cosas que preparamos arriba ya podemos hacer ventas en Paypal, pero esta implementación tiene grandes fallas: Para empezar, el hecho de registrar una venta en este caso (osea, generar una cotización que más tarde puede ser pagada en Paypal) no quiere decir necesariamente que la venta se haya realizado, por lo tanto, tenemos que tener una manera de rectificar que el pago de una "cotización" fue exitoso. Ahora, en mi caso uso un carrito volátil basado en sesiones, por lo que siempre que creo una venta éste se vacía por sí solo... En la mayoría de los casos si tu app tiene una fuerte integración con paypal o una implementación de cart tradicional esto no será así, por lo que debes generar un método que te permita limpiar el carro en el momento que  una orden fue pagada de manera que si el cliente quiere hacer otra los items anteriores no se le sumen a su total. Empecemos por reparar estas cuestiones:

Para hacer que todo esto funcione como debe, tenemos que usar el servicio de Instant Payment Notification o IPN de Paypal y para esto, crearemos un nuevo recurso en nuestra aplicación:

rails g scaffold payment_notification hash_params:hash card_bundle_sale_id:string status:string transaction_id:string

Borramos todas las vistas de este recurso y nos vamos a su controlador, (mismo que tenemos que vaciar) para poner este código:


Recuerda pasar correctamente los atributos de tu cart_id (card_bundle_sale_id en este caso) y el hash de tus parámetros según tu caso práctico... Si estuviéramos usando ActiveRecord esto del hash se tendría que hacer serializando el atributo params del modelo para poder tener los parámetros que paypal nos suelte en un hash cuando lo ocupemos. En Mongoid no, porque MongoDB almacena todo en JSON Objects.

Ahora configuramos nuestra notificación de pago en su modelo y el código queda más o menos así:



Aquí lo que estoy haciendo yo es crear un callback que hará que una vez creada una notificación de pago (al tener una compra exitosa por medio de paypal) marcará dicha compra como "pagada a tal hora" entonces en mi listado de ventas del que les hablé antes aparecerá la fecha y hora del pago y eso me permitirá saber 3 cosas: 1) si una orden está pagada 2) cuantas órdenes en promedio se pagan por c/u que se arma en la web y 3) cuándo le puedo contar al cliente como pagado su pedido. Para que esto fuera posible tuve que modificar mi modelo de Card Bundle Sale un poco y quedó así:



Lo que hice aquí fue añadirle las Mongoid Timestaps al modelo para poder tener los atributos del campo "purchased_at" funcionando y le añadí dicho campo al modelo, también lo añadí a la vista de Sales#Index donde se registran todas mis "ventas" (o más bien "cotizaciones") para un control más estructurado y que los administradores puedan ver cuando algo ha sido pagado y exactamente en qué momento.

Ahora necesitamos Limpiar el carro cada que se haga una compra exitosa. En mi caso esto no es necesario ya que mi carrito es "volátil" pero para aquellos que tengan un cart "hard_coded" algo como esto podría ayudarles, aclaro que esta es una de esas cosas que es muy específica de cada aplicación/contexto y puede que en tu caso esto aplique/te sirva o no, veamos:

En el application_controller:

def current_cart
  if session[:cart_id]
    @current_cart ||= Cart.find(session[:cart_id])
    session[:cart_id] = nil if @current_cart.purchased_at
  end
  if session[:cart_id].nil?
    @current_cart = Cart.create!
    session[:cart_id] = @current_cart.id
  end
  @current_cart
end

Sólo nos queda hacer los cambios pertinentes a nuestro workflow paypal y en mi caso fue así:

Añadí el parámetro y argumento de notify_url a mi método "paypal_url" en mi modelo de "orden" (card_bundle_sale en este caso):



Luego en mi acción create de sale, le pasé la nueva ruta al redirect_to:


Y finalmente, lo testeamos desde consola fingiendo una notificación directo al servidor con:

curl -d "txn_id=ID_TXN&invoice=ID_CART&payment_status=Completed" http://localhost:3000/payment_notifications

Donde ID_TXN es el id de transacción que te genera paypal al pagar e ID_CART es el id de tu objeto cart, (en este caso card_bundle_sale) asociado a la venta en cuestión, veamos un ejemplo en vivo:



¡Bien! Pero no hemos acabado todavía jajaajaja!

4) Encriptación de operaciones

Por muy bonito que se sienta el haber armado esto, todavía no hemos terminado, ahora tenemos que evitar que alguien pueda alterar las transacciones pasando los parámetros de forma encriptada en lugar de por la pura URL. ¿Porqué? Porque si no lo hacemos así, nos pueden cambiar el precio de un producto y "llevárselo" por $0 y no queremos eso... Veamos pues:

Lo primero que haremos será correr una secuencia de comandos para generar unos certificados SSL que usaremos para identificar nuestra webapp con Paypal:

1
2
3
4
5
6
cd myapp
mkdir certs
cd certs
openssl genrsa -out app_key.pem 1024
openssl req -new -key app_key.pem -x509 -days 365 -out app_cert.pem
mv ~/Downloads/paypal_cert_pem.txt paypal_cert.pem

NOTA: Necesitas tener OpenSSL instalado

("myapp" allá arriba se refiere al nombre de la carpeta de tu aplicación) El 5to comando nos pedirá unos cuantos datos, los rellenamos y proseguimos lléndonos a "Perfil>Certificados para Sitio Web" (se puede llamar ligeramente la opción en cada una de las interfaces de paypal pero buscamos la de los pagos codificados para ser exactos). En esta ventana añadiremos nuestro archivo app_cert.pem, anotaremos el id de certificado que paypal le dé y finalmente descargaremos el certificado público de paypal y lo guardamos en nuestro directorio "certs" de la aplicación, renombrándolo a "paypal_cert.pem":


Ahora cambiaremos un poco nuestro proceso de checkout y configuración de la aplicación. Al momento que estoy haciendo esto (pues es en vivo mientras trabajo) decidimos sí mostrar una página extra de confirmación de orden antes de enviar al cliente a pagar en esta app (hasta el momento no lo hemos hecho) puesto que paypal permite muy pocos parámetros de personalización para la página donde se muestra la información de la orden y eso no propicia una buena experiencia de usuario; Veamos entonces cómo quedó todo esto:

Archivo YAML

Usaremos un archivo de configuración global YAML para pasar algunas de las variables que ocupamos para nuestro checkout de manera transparente y uniforme en nuestra aplicación. Para hacer esto, creamos 2 archivos:

config/initializers/load_app_config.rb:


config/app_config.yaml:


El primer archivo simplemente le dice Rails donde encontrar al segundo y qué hacer con él. El segundo es un archivo a donde se mueven todas las variables usadas (o las más importantes pues) en el proceso de checkout, de manera que evitemos repetición y todo esté mejor organizado y limpio. Nótese que en el entorno de producción la URL de paypal se pasa a la normal y ya no a la del sandbox.

NOTA: El "secret" puede ser lo que tú quieras.

Cambiando el proceso de Checkout

Ahora voy a cambiar mi proceso de checkout. Para esto, simplemente cambiaré el condicional de mi acción create de sale (esto en mi caso específico) para que una vez registrada una orden/venta en lugar de llevar el cliente a pagar directo a paypal lo lleve a revisar su orden en la vista show de la misma (la del card_bundle_sale que genera el cliente al armar su orden en nuestro caso):


Y luego, en esa vista a donde mando el cliente crearé un botón de checkout especial que lo que hará será mandar un form con campos ocultos para poder generar el ente de checkout que necesitamos:


Aquí lo que hago es hacer una forma para armar la nueva paypal_url encriptada, toma especialmente 2 campos que ocupa: cmd y encrypted. Puedes usar la misma forma en cualquier situación pero sólo recuerda cambiar mi "cart_bundle_sale" por el objeto que represente tu orden en tu escenario.

Más tarde debemos cambiar los métodos y callbacks especiales de nuestro modelo que represente las órdenes (card_bundle_sales en este caso) por algo como esto:



Como verán, es básicamente el mismo archivo, pero ahora el método se llama "paypal_encrypted" en lugar de "paypal_url" y los parámetros que tenemos en el YAML son llamados como parámetros de la constante [APP_CONFIG], También añadimos el campo de "cert_id" que no teníamos antes y al término de nuestro método iterante llamamos otro método que se llama "encrypt_for_paypal" pasándole como argumento el resultado de nuestra iteración. Más abajo está definido el método encriptador y ése lo puedes copiar y pegar si quieres, funciona bien para todos los casos. Guardamos ese archivo y proseguimos:

Accediendo a las variables del YAML

Ahora sólo nos queda cambiar nuestro callback en el modelo de payment_notifications para que revise bien los atributos más importantes de la transacción y si es que todas nuestras ammm... "validaciones" pasan sin errores, haga su trabajo, (también podríamos programarlo para que si no pasa, nos mande un correo avisándonos o como quieran, pero yo lo dejé así), De igual manera ahora está configurado para usar nuestras variables globales, el dichoso callback queda así:



Una vez que hemos configurado esto, ¡hemos terminado oficialmente! Tenemos una integración completa, funcional y segura de Paypal en nuestro sitio/aplicación web...

Tuitea Esto:
Integrar #Paypal con #Rails y no morir en el intento #Mongoid #DesarrolloWeb - http://bit.ly/XBYowb vía: @xenodesystems - Tweet!

P.D. Este tutorial está basado en las lecciones del increíble Ryan Bates de railscasts.com, si quieres aprender más sobre la integración de paypal (o cualquier tema rails) te recomiendo que le eches un ojo a su sitio web, por cierto, este post se agregará a nuestro curso gratuito de Ruby on Rails para que lo chequen desde el principio y aprendan Rails si quieren.

sábado, 13 de abril de 2013

La extraña historia de la MicroSD infinita y cómo reparar un directorio que se convirtió en archivo en Linux


Hace rato me trajeron a revisar una MicroSD con un problema muy peculiar: Tenía una especie de virus o error bastante curioso que hacía que todas las carpetas se multiplicaran infinitamente hasta que (en el caso de windows) la ruta fuera tan larga que no se pudiera accesar, y los archivos de la SD en teoría estaban hasta el fondo porque aunque todas estas carpetas señuelo estaban vacías, la SD tenía 2GB llenos y eso tenía lógica pues estaba llena de videos según me comentó el cliente.

Cuando escuché del problema lo primero que pensé fue "voy a usar ls, find o algún comando similar para saber donde están los archivos y extraerlos desde la consola" pero el loop era infinito y cada que accesabas a una carpeta se creaba otra del mismo nombre infinitamente impidiendo que vieras los archivos. Intenté usar varios métodos para listar directorios y archivos pero sólo conseguía lo mismo: Loop infinito, incluso me pareció extraño porque intenté conectar una USB aparte (en mi máquina Linux donde estaba arreglando esto) y de pronto el proceso del loop se apoderó de ella (no dejándome extraerla con seguridad ni nada) pero no se infectó con el virus obviamente. Después de unos minutos de tener la MicroSD montada, la RAM se empezó a saturar, pues el proceso continuaba infinitamente y tuve que cerrar la sesión.

Cierro la sesión y al volver me doy cuenta de que alguno de los comandos de lectura que apliqué desde la consola al Filesystem había activado un proceso como de protección del virus que la MicroSD tenía y me había convertido mis directorios en "datos brutos" que a simple vista son archivos ilegibles con nombres súper extraños y el filesystem se había vuelto de sólo lectura, por lo que ni cambiar el nombre de éstos podía.

Cómo lo reparé:

En este momento, había dado todo por perdido pero el cliente (que resulta ser una amiga mía de mucha confianza) estaba viéndome trabajar y estaba súper consternada porque esos videos eran un trabajo final para la universidad, por lo que fingí que no pasaba nada malo y continué.

Los directorios (carpetas) de la MicroSD se habían vuelto archivos de data pura que eran ilegibles para cualquier programa pero guardaban en su escencia (a juzgar por el diálogo de propiedades) su alma de "directorio" Esto es complicado de explicar, pero imagínense un archivo binario ilegible que dentro tiene "nada" con un nombre como "á.é.í.O.ü.." (sin extensión) que al darle en propiedades nos dice que es un "ente" del tipo carpeta. Por otro lado no podía ni cambiarles el nombre ya que el Filesystem se había vuelto de sólo lectura y por tanto NI ROOT tenía poder sobre la MicroSD. Lo primero que pensé por esto fue hacer un "remontaje" con el siguiente comando:

sudo mount -o remount,rw  '/ruta/a/MicroSD'

Cosa que me volvió el filesystem legible y pude cambiar los nombres de todas las carpetas de jalón, pero al hacerlo perdieron su condición de directorio y se habían convertido en NADA. Si al principio estábamos mal, este era el final jajaajaja!.... Ya estaba por rendirme cuando seguí investigando y me topé con el caso de un tipo al que le pasó esto pero en su disco duro, la parte importante de su anécdota decía:

The fix for me was to reboot into level 3 as root and unmount /home, then running an fsck -f on the hard drive, then I rebooted and the files had been converted back into directories and none of my files were lost or corrupted.
So, eso me animó. Abrí Gparted, chequé la ruta "/dev" de la MicroSD problemática y le pasé una barrida con fsck (para ser sinceros no me di cuenta de si estaba montada o no en ese momento, asumo que no) con el siguiente comando:

sudo dosfsck -w -r -l -a -v -t /dev/sdcX

Y voilá! retiro la MicroSD, la vuelvo a introducir y entre todos los datos en bruto "vomitados" después de la reparación con fsck salen los archivos de la muchacha. Pero la cosa no acabó ahí: Debido a que son archivos "Reintegrados" tuve que tomar todos los que fueran videos (que resultaron estar en un formato "bruto" llamado REC) Y abrirlos 1 por 1 con VLC para que "vomitaran" los metadatos sobrantes. Esto igual es difícil de explicar, pero en resumen, cuando esto pasa se tiene que abrir cada uno de los archivos rescatados para que "vomite" metadatos sobrantes (algún thumbnail o data pura) y una vez abiertos y verificados (ya soltando los extras) el archivo queda 100% listo para su uso. En el caso de estos videos los revisé con VLC y los convertí de REC a AVI con FFmpeg para que la muchacha los pudiera trabajar (ya que más bien la cámara los guardaba en MOV pero por el proceso de restauración quedaron en un formato bruto que difícilmente se puede trabajar con plataformas diferentes a Linux para lo que ella necesitaba (edición de los videos con algún software básico).

Y aquí termina mi anécdota del día, me pareció algo bastante curioso que tenía que compartirles, a ver si algún día les sirve esta experiencia que relaté.

viernes, 12 de abril de 2013

[Diseño Web] Obtener paleta de colores de/para un sitio web


Este es un tip bastante sencillo que me gusta utilizar cuando estoy diseñando algo y de pronto me encuentro con que "me faltan colores" para acabar de formar un sitio web o diseño. También me he encontrado con que veo un sitio web y me gustan sus colores y pienso en usarlos o combinarlos con otros para hacer un nuevo diseño pero quiero saber cuáles son sin hacerles pick uno por uno... De igual manera a veces armo un logo por ejemplo y quiero usar esos mismos colores para armar la web del cliente, pero necesito lo más posible en espectro para armar dicho diseño de página; A continuación, les enseñaré cómo es que lidio con estas situaciones

Obteniendo colores

Para resolver esto, es tan simple como tomar una foto a pantalla completa de mi diseño o sitio web deseado en Chrome y utilizar la extensión palette para revelarme todos los colores posibles en combinación, veamos entonces:

Tomo la captura


Nótese que omití todas las partes del navegador web, en este caso es la web de una agencia de viajes que estoy haciendo ahorita y me hacen falta colores para el nuevo logotipo que voy a armar. Tomas la captura de una parte que tenga la mayoría de colores disponible de tu paleta actual y entonces te instalas la extensión Palette para chrome.

Subo la imagen a algún lado

Puede ser a donde quieras, lo que necesitamos es que resuelva a una URL para que palette le pueda sacar los colores, lo hacemos y abrimos la URL que resuelve a la imagen en el navegador. Le damos click secundario del ratón y le pedimos a Palette que nos dé una paleta personalizada:


Obtengo mi paleta

Ahora ya puedo elegir de cuántos colores quiero mi paleta (de 8 a 64) y el resultado es el siguiente:


En este caso sólo saqué 30 colores, pero puedo sacar más si lo considero pertinente. Con este método podemos obtener una paleta de colores amplia a partir de cualquier imagen en la web y así complementar nuestros diseños, partiendo las imágenes o capturas en los diversos colores que las forman.

lunes, 8 de abril de 2013

Tómate 5 minutos para entender TU VIDA... [VIDEO]



A Deep And Awesome View on life from a 9-Year-Old Boy


No suelo hacer esta clase de posts, pero la verdad este video me impactó un tanto... Lo encontré navegando por la red y últimamente se ha hecho muy viral, se trata de un video donde un niño de 9 años nos explica qué es lo que él opina acerca de una cantidad de temas de existencialismo tales como:

  • ¿Quiénes somos?
  • ¿De dónde venimos y hacia dónde vamos?
  • ¿Hay un destino escrito?
  • ¿Cuál es el significado de la vida? 
  • ¿Hay vida en otros planetas? 

y demás cuestiones similares... Aunque es tentador pensar que el material estaba ensayado, viéndolo con los ojos de un espectador y no de un escéptico, más allá de todo, creo que el planteamiento que el niño da sobre los diversos temas comentados es algo muy válido e interesante ya que nos habla de todos estos temas sin necesidad de meter cuestiones como divinidad, sociología u otros factores externos de los que un adulto se agarraría para dar una explicación similar al respecto contaminada de algún modo con una serie de ideologías "precargadas" a lo largo de su vida.

Tarde que temprano, todos entramos en una etapa donde queremos respuestas de un montón de cosas que escapan de nuestro control... Yo estaba pensando justamente en temáticas similares cuando de pronto, me topé con el video, me gustó y se los comparto (Está en inglés). Me gustaría que se tomaran 5 minutos de su día para verlo y si quieren podemos plantear diversas opiniones en los comentarios, eso sería enriquecedor ;)


¡Que tengan un buen día!

domingo, 7 de abril de 2013

Instalar Google App Engine (Launcher y SDK's) en Linux


Google App Engine es algo que me gusta muchísimo: Se trata de una plataforma de desarrollo para aplicaciones web que corren dentro de la nube de Google. GAE tiene muchísimo potencial, al soportar lenguajes como Python y Java (además de todos los que se pueden implementar por medio de "mashups" de Java como PHP y Ruby por sólo mencionar algunos); Nos permite dar rienda suelta a nuestra imaginación y trabajar por una web mejor completamente gratis.

El motivo de éste post es mostrarle a los usuarios de App Engine cómo tener todo un entorno de trabajo completo para usar ésta plataforma dentro de Linux, enseñándoles cómo trabajar con los SDK de Python y Java, además de cómo instalar el Google App Engine Launcher dentro de su distribución Linux favorita y armar un set de aplicaciones útiles para comenzar a desarrollar cómodamente. Comencemos:

1) Preparando el entorno

NOTA: Antes que nada, debemos instalar los 2 lenguajes base de App Engine en nuestra Distro; Python viene de serie en prácticamente todas las distros, y en el caso de java, basta con buscar los nombres "openjdk" y "icedtea" en nuestro gestor de paquetes para instalar los paquetes necesarios según la distro (Necesitaremos el JDK, el JRE y el plugin para web además de los paquetes devel). Una vez instalados los lenguajes, podemos comenzar:

Lo primero que haremos será crear una carpeta llamada "GoogleAppEngine" dentro de nuestra carpeta personal, después Descargaremos los dos SDK disponibles, para Python y Java y los extraeremos dentro de ésta carpeta recién creada. Tras descargados y extraídos, podemos eliminar los comprimidos ZIP de cada uno y cambiamos el nombre a las carpetas resultantes de la extracción a "GAE-PythonSDK" y "GAE-JavaSDK" respectivamente.

2) Instalando el Google App Engine Launcher

Para ésto necesitaremos instalar dos paquetes primero en nuestra distro (dependiendo la distro, los comandos de instalación cambian) en éste ejemplo usaré Fedora como distro de trabajo por motivos de comodidad; Pero si no usan Fedora, sólo deben cambiar el comando de instalación por el que se ocupe en su distribución de turno con su gestor de paquetes:

1
2
sudo yum -y install subversion 
sudo yum -y install python-wxversion wxPython

Tras conseguido el software necesario para trabajar con el launcher, lo descargamos en nuestra carpeta "GoogleAppEngine" con:

1
2
cd ~/GoogleAppEngine
svn co http://google-appengine-wx-launcher.googlecode.com/svn/trunk

Nos daremos cuenta que ésto nos genera una carpeta llamada "trunk" dentro de la carpeta "GoogleAppEngine", renombramos ésa carpeta "trunk" como "GAE-Launcher" y podemos proseguir creando un lanzador en nuestro escritorio (o menú de aplicaciones) si así lo queremos. Los datos que podemos requerir serían:

Nombre: Google App Engine Launcher

Descripción: Google App Engine Launcher

Orden: ~/GoogleAppEngine/GAE-Launcher/GoogleAppEngineLauncher.py

Ruta de Trabajo: ~/GoogleAppEngine/GAE-Launcher

Ícono: http://goo.gl/Tn1yk

3) Aplicando Configuraciones necesarias

Ahora tenemos que ejecutar el Google App Engine Launcher, y modificar ciertas preferencias. Lo abrimos y nos mostrará una advertencia de que faltan algunas cosas como ésta:


Le damos aceptar y en el Launcher nos vamos a "Edit>Preferences" en la ventana que aparecerá tenemos que tener los siguientes parámetros configurados:


Recuerden cambiar "user" por su nombre de usuario en la ruta del "App Engine SDK", los campos de "Editor" y "Deployment Server" como pueden ver en la imagen se dejan vacíos. Hecho ésto, cerramos y volvemos a abrir el Launcher y entonces podemos empezar a trabajar con Google App Engine desde una interfaz gráfica, añadir nuevas aplicaciones y demás.

NOTA: Para que las aplicaciones puedan ser gestionadas desde el Launcher, primero hay que copiar sus respectivas carpetas a /home/user/GoogleAppEngine/Python-JavaSDK Según el entorno que estemos utilizando, las aplicaciones que tengan base Python obvio irían a "GAE-PythonSDK" y las base Java obvio van para "GAE-JavaSDK"; Recuerden que la ruta de aplicación que deben de dar al launcher es la de la carpeta copiada dentro del directorio del SDK correspondiente según el lenguaje que estemos usando para desarrollar...

Extra: Herramientas de Trabajo

Para desarrollar Aplicaciones GAE en Linux, sólo necesitarás algunos programas como:

Editor de Texto Kate/Kwrite/Gedit - Vienen en los repos de todas las distros, Kwrite y Gedit suelen venir pre-instalados, en mi opinión personal, Gedit vitaminado es la mejor opción para desarrollar.

Editor Web Bluefish - http://bluefish.openoffice.nl/index.html (Está desde repos en cualquier distro)

Acá les dejo un Screenshot de mi Google App Engine funcionando sobre de Fedora KDE:


P.D. Como muchos de ustedes quizá ya saben, App Engine ya también tiene soporte para el lenguaje de programación "Go" de Google, pero como no encontré mucha información sobre éste no lo traté en éste post.

viernes, 5 de abril de 2013

[QuickTip] Cómo hacer gksudo/gksu en Fedora


Para los que no lo hayan notado, en fedora no es posible hacer "gksudo/gksu" directamente, esto es por motivos de seguridad. Lo que hacen estos comandos es permitirnos usar aplicaciones gráficas en modo root, tales como el gestor de archivos. La diferencia entre esto y hacer sudo directamente radica precisamente en que los comandos de arriba son específicos para acceso gráfico root mientras que sudo debería ser usado para la terminal más que nada.

En Fedora no existen los comandos antes mencionados pero si tenemos una alternativa llamada beesu. Para poder usar beesu, se instala primero:

sudo yum -y install beesu

y luego ya se puede usar cómo usaríamos normalmente "gksudo/gksu" por ejemplo:

beesu nautilus

Nos abriría el gestor de archivos nautilus en modo root. Cabe destacar que os usuarios de KDE por otro lado, sí pueden usar kdesu (alternativa a gksudo en KDE) sin problemas en Fedora. Este tip es necesario para los demás entornos de escritorio solamente.