viernes, 10 de mayo de 2013

Malas noticias

Aparentemente googlevoice no funciona en Argentina.. asi que la solucion que habia pensado que iba a funcionar para poder usar WhatsApi para enviar mensajes desde la PC no se va a poder utilizar...

Espero mañana poder tener novedades!.

jueves, 9 de mayo de 2013

Enviar mensajes con Whatsapp desde la PC

No se descubre nada si se dice que Whatsapp esta siendo cada vez más popular, y creo que la siguiente es una pregunta que nos hemos hecho varios ¿Se pueden enviar mensajes utilizando una PC por medio de Whatsapp?. En primera instancia y sabiendo que los mensajes de Whatsapp son enviados vía Web (Es decir no utiliza las lineas telefónicas) podríamos decir que si es posible, ahora la pregunta del millón es ¿Como?.

Bueno, la forma mas "sencilla" y directa es instalar un emulador de Android en nuestra computadora, y luego instalarle Whatsapp, configurarlo y LISTO!.

No gastaremos tiempo en explicar como hacer la descarga de BlueStack ya que esta lleno de tutoriales dando vueltas por la web, ni tampoco explicaremos como hacer la configuración de WhatsApp, ya que también se encuentra en muchos sitios. Para los mas perezosos aquí les dejo el link en donde se muestra como instalar BlueStack y como configurar WhatsApp.

Tutorial instalacion BlueStack configura WhatsApp

Para la gran mayoría de las personas, la instalación de este emulador y la configuración de WhatsApp, seria suficiente para satisfacer sus necesidades, de todas formas a muuuuuuuchos les gustaría tener mas control sobre lo que se puede hacer, como enviar mensajes de forma automática, o realizar alguna acción algo mas compleja al recibir un mensaje.

Seguramente que si llegamos a este punto, contamos con algún conocimiento al menos básico de programación ya que tenemos que empezar a ver cosas algo mas complejas.
Solo como anécdota, les puedo contar que la gente de WhatsApp se encuentra muy pero muy reacia a la posibilidad de que los usuarios tengan algún tipo de control sobre el envió de mensajes desde fuera de los teléfonos moviles, quizás sea un tema de estructura o de capacidad, no se bien a que se debe, pero se que están permanentemente realizando actualizaciones que hacen laburar cada vez mas a los cráneos que han logrado desenmarañar por medio de ingeniería inversa las directrices de la comunicación por medio de WhatsApp.

Como la mayoría sabe, el nombre de usuario en WhatsApp no es ni mas ni menos que el numero telefonico competo del usuario, con esta idea innovadora los creadores de WhatsApp lograban desligar al usuario final de los tediosos pasos para la registracion de sus cuentas, sin embargo como todos sabemos Whatsapp no solicita un password a la hora de loguearnos al sistema, sino que genera uno en base a de algunos datos de nuestro telefono movil. En primera instancia era un md5 del IMEI invertido, luego fue un dato en base64 del mismo imei o de la MAC de acuerdo al sistema operativo que se utilizaba. El tema es que habian graves problemas de seguridad, ya que teniendo el numero de telefono y el imei o la MAC de un telefono ajeno, se podia suplantar la identidad de alguna persona, y hasta incluso segun cuenta la leyenda se podian leer conversaciones y cambiar foto de perfil y estado de WhatsApp... :)...

La ultima medida que tomaron los señores "Whatsapperos" fue brindar una clave mas compleja a sus usuarios, y por lo tanto mas dificil de comprender su armado. De todas formas hecha la ley, hecha la trampa.. :)..

Existe una API (Application Programming Interface), ingeniosamente llamada WhatsApi, que se ha desarrollado y se ha liberado al mundo, la misma permite tener control sobre gran parte de la mensajería de WhatsApp, lamentablemente esta API "deschavo" algunos de los graves problemas de seguridad con los que contaba WhatsApp, por lo cual la empresa comenzó acciones legales contra los creadores para que bajen dicha API de la Web, de todas formas ya se había extendido demasiado, por lo cual a estas alturas es casi imposible evitar que cualquiera pueda tenerla en sus manos. Por este motivo a la gente de WhatsApp Inc. no les quedo otra que poner manos a la obra y tratar de tapar esos baches. Ahí es que comenzó el tire y afloje entre los dueños de WhatsApp y los creadores de WhatsApi, el sistema de mensajería realizaba cambios en su validación de usuarios y la comunidad actualizaba la API para soportar ese cambio. Ahora se llego a un punto en el que no se ha podido descifrar el método de creación de la clave, peroooooooooooooo, aún así se puede seguir usando esta API.

Por ahora solo dejare un link en donde dice cuales serian los pasos a seguir para poder comenzar o continuar trabajando con WhatsApi. Aún no he podido probar a fondo esta solución, pero en breves lo haré y lo comentare para que haya algo en Español.

Continuar usando Whatsapi

Eso seria todo por ahora. Nos estamos viendo en la próxima publicación.

jueves, 7 de marzo de 2013

Recomendada programacion orientada a objetos PHP

Ya hace un tiempo que programo con PHP, cerca de 2 años, el tema es que hasta hace 1 mas o menos no comprendía los beneficios de programar orientado a objetos (Ojo no soy un purista de esto, si me queda mas sencillo resolver algo proceduralmente lo haría sin ponerme colorado). 

La estructura basica que estoy usando es una forma de "modelado" en la cual por cada clase tengo dos clases, una que se ocupa de toda la comunicacion con la Base de datos y otra que es el objeto propiamente dicho al cual simplemente le envio mensajes tales como:
  • $usr = Usuario::obtenerPorId($id) y me devuelve un objeto Usuario al cual luego le puedo hacer cosas tales como  $usr->getNick() y me devolvería el nombre de usuario.. :)
Entonces si vamos al ejemplo de la clase usuario tendría las siguiente clases:
  • Usuario.php
  • dUsuario.php
Con estas clases podria resolver toda la lógica. 

La clase Usuario tendría toda la lógica incluyendo los geters y los seters y se ocuparía de hacer el mapeo a objetos de las tablas relacionales. 
Yo para hacer esto suelo tener un método estático que se ocupa de hacer dicho mapeo.
Simplemente le paso un registro de la base de datos obtenido con mysql_fetch_array o con mysqli.. :)

public static function  mapearTablaConObjeto($reg){
    $usuario = New Usuario();
    $usuario->setNick($reg["nombre"]);
    $usuario->setMail($reg["mail"]);
    $usuario->setPass($reg["clave"]);
    $usuario->setSid($reg["sid"]);
    $usuario->setIp($reg["ip"]);
    $usuario->setIdUsuario($reg["idUsuario"]);
    $usuario->setUltimaAccion($reg["ultima_accion"]);
    $usuario->setOnline($reg["online"]);
    $usuario->setPerfil($reg["perfil"]);
    return $usuario;
}

Basicamente la clase Usuario suele devolver un usuario en particular o un arreglo de varios usuarios.
Para mostrar un ejemplo voy a poner obtenerUsuarioPorId($id)

    /*
     * OBTIENE UN USUARIO A PARTIR DE UN ID
     */
    public static function obtenerUsuarioPorId($idUsuario){
        $reg_usuario = dObtenerUsuarioPorId($idUsuario);
if(!is_null($reg_usuario)){
    return Usuario::mapearTablaConObjeto($reg_usuario);
}
return NULL;
    }

Aquí lo que se hace es llamar a la función que se encuentra en dUsuario.php y se ocupa de obtener un usuario de la Base de Datos. 

Nota: Es importante que los datos lleguen validados. Es decir que si tiene que entrar un entero, sea un entero y que si tiene que ser una cadena sea una cadena valida. 

La función dObtenerUsuarioPorId($idUsuario) se veria como sigue:

function  dObtenerUsuarioPorId ($id){

    global $conexion;

    $registros = mysql_query("select * from usuarios 
                              where idUsuario=$id",$conexion) or
    die("Problemas en el select USUARIO:".mysql_error());
    if(mysql_num_rows($registros))
return mysql_fetch_array($registros);
    return NULL;
}

Puede verse que la dObtenerUsuarioPorId obtiene un usuario por un id, y en caso de que no recupere ninguno devuelve NULL, la funcion obtenerUsuarioPorId si recibe NULL devuelve NULL y si recibe un registro hace el mapeo y devuelve el objeto usuario!! para ser utilizado como plazca. 

Luego se podrían hacer cosas tales como:

include_once "Usuario.php";

$usr = Usuario::obtenerUsuarioPorId(1);
if(!is_null($usr)){
    echo $usr->getNick();   // Muestra el nick del usuario 1
    // Cambio el nick del objeto pero no lo persisto en la BD
    $usr->setNick("Otro nick");  
    echo $usr->getNick();  // Muestra "Otro nick"
    $usr = Usuario::obtenerUsuarioPorId(1); // Vuelvo a obtener el usuario 1
    // Como no lo habia guardado en la BD vuelvo a mostrar el nick del usuario 1
    echo $usr->getNick(); 
    // Cambio el nick del objeto pero aún no lo persisto en la BD
    $usr->setNick("Otro nick"); 
    // Guardo los cambios en la BD. Si el usr->isNew() inserto sino actualizo
    $usr->save();  
    echo $usr->getNick();  // Muestra "Otro nick"
    $usr = Usuario::obtenerUsuarioPorId(1); // Obtengo el usuario 1.
    echo $usr->getNick();   // Muestro "Otro nick" porque ya habia guardado los cambio. :) 
}

Espero que se haya entendido más o menos cual es mi idea, porque fue una explicación medio rapida.. :).. cualquier consulta hagan!. jeje 

Saludos! 

El proyecto de un juego de navegador

Bueno el proyecto del juego de navegador quedara relegado por el momento... :). es necesario a mi entender tener ciertos privilegios sobre la Base de Datos que en el servicio de hosting con el que cuento no los tienen (Y tampoco tengo el dinero para invertir, no es mucho pero tengo otras prioridades por el momento).

Para hacer que un juego on-line funcione, le cuento a los mas despistados tienen que resolver casi todo del lado del servidor sin estar obligado a que el usuario intervenga ni este conectado.
El usuario simplemente ejecuta una acción

Por ejemplo:

  • Transportar recursos o realizar un ataque.

Pero no tiene que ejecutar ninguna acción para que el transporte llegue a destino, simplemente envía y espera a que pase el tiempo necesario para que la acción concluya, el usuario puede estar conectado o fuera de linea al momento de la llegada, pero lo que es seguro es que la acción debe finalizar igual.. :)

La forma que encontré de desarrollar esta "Asincronidad" o "Desatendimiento" de las acciones fue utilizar Eventos de la Base de datos.. :)

En un primero momento lo hacia con javascript que cuando viera que se terminaba un tiempo revisara que se había finalizado... perooooo eso obliga al usuario a estar conectado o al menos con el navegador abierto.. jejeje detalles de diseño..

Si a alguno se le ocurre otra idea bienvenida, pense en usar Cron pero no hubo caso.

jueves, 27 de diciembre de 2012

Nada en particular.

Hace ya poco más de un mes que comencé un proyecto Web personal, de esos en los que se suele invertir mucho y que seguramente nos dejara poca ganancia monetaria pero mucha, mucha intelectual, cuyo valor no es para nada despreciable.. :)

Comencé a hacer un juego de navegador. Siempre me llamaron la atención algunos juegos simples pero no por ello poco "enviciantes". Me preguntaba que es lo que habría detrás de esos juegos, que tanta estructura de personal y que tanto hardware sería necesario para hacer y mantener un juego on-line.
Por ahora el proyecto es unipersonal y lo vengo llevando bastante bien.. Creo que todo esta en el análisis y en saber hacia el lugar al que debe ir el proyecto.. Lo cual no se limita únicamente a los juegos, sino que es extensible a cualquier proyecto software.

Con este proyecto me estoy dando cuenta de algunas cosas bastante agradables. Por ejemplo:

  • Que no hace falta usar grandes framework para hacer un buen trabajo web con PHP. 
  • Que las formas de evitar los ataques de XSS, no son tan complejas como muchos nos quieren vender.
  • Y que se puede ser prolijo programando con PHP.. jeje

Si quieren que les di una mini receta para evitar los ataques de XSS, sería:


  1. Validar todos los datos de entrada, que puedan llegar a la Base de datos. Si son datos de tipo Entero, validar que nos hayan ingresado solo valores enteros. :).. con PHP asi como con la mayoria de lenguajes de programación de alto nivel, esto es muy sencillo y se resuelve en una sola linea.. 
  2. Si los campos que les pueden ingresar, son de tipo texto la validación es un poco mas complicada, porque siempre esta la posibilidad que nos quieran inyectar código si no dejamos controlados caracteres tales como las comillas simples (').
Si hacemos que a partir del ingreso de un formulario si ejecute algo similar a esto:

select * from tabla1 where nombreCampo = 'Valor ingresado desde el formulario';

estariamos dandole la posibilidad a algun usuario malicioso de ingresar en el formulario por ejemplo el valor.

' basura

Con lo cual fallaría la sentencia SQL si esto no esta controlado y quizas el error obtenido le daria pistas al usuario mal intencionado de obtener información acerca de la estructura de nuestra Base de datos que no queremos que sea pública.

Para hacer la validacion de campos de texto, lo que puedo recomendar es 

hacer la conexión con mysqli de la siguiente manera:

$conexion = new mysqli("<hostname>", nombreUsuario, password, nombreBaseDeDatos);

Esta forma de conexión nos brinca la posibilidad de utilizar las sentencias prepare y bind_param

Prepare sirve para "preparar" la consulta que luego querremos ejecutar en la base de datos, y nos permite dejar sin enlazar los parametros, son el uso de los signos de pregunta (?). 

$consulta=$conexion->prepare("insert into tabla
   (valorEntero1,  valorEntero2 , valorCadena,  valorEntero3) 
values 
(?, ?, ?, ?)");

Luego con la sentencia bind_param, bindeamos los signos de preguntas con los valores que le queremos pasar a la secuencia SQL. El primer parámetro de bind_param es una cadena con el formato de los parámetros que se insertaran a continuación. "iisi" significa que el primer parámetro es (i) (INTEGER), que el segundo parametro es (i) INTEGER que el tercer parámetros es (s) STRING y que el cuarto y último parámetro es (i) INTEGER. 
$res = $consulta->bind_param("iisi",$val1,$val2,$str1,$val3);
if($res){
$res = $consulta->execute();
        }

Con esto tendríamos validados los campos de tipo texto... Previo a hacer el binding, deberíamos comprobar que los valores integer, sean realmente enteros. Ya que en mi versión no se porque razón no falla cuando le envió cadena en los datos de tipo entero. :)



Bueno solo quería contar esa pequeña experiencia..
Supongo que seguiré comentando algunas cosas más de mi desarrollo en los dias subsiguiente..

sábado, 10 de noviembre de 2012

Framework Python

Bueno lo prometido es deuda.. :)..

Así que pasare a mostrar mi framework.

Básicamente es un framework que sirve para hacer aplicaciones de escritorio utilizando Python, hace uso de un ORM que es SqlAlchemy y para la parte de interfaz gráfica utiliza PyQT... Cabe aclararar que esta es una primera aproximacion a lo que realmente estoy buscando... por lo cual tiene varias cosas que pulir, y el que quiera colaborar puede hacerlo.. :)..

Por ahora tiene soporte solo para las Bases de Datos:

  • SQLite
  • MySQL
Pero es fecalmente extensible a PostgreSQL.

Es importante como dije en el vídeo seguir ciertas convensiones, la principal es que el nombre del archivo con el cual se guarda el Form, sea igual al nombre del objeto form.. :). el resto practica mente queda a gusto del usuario..

En cuanto a la definición del modelo, hay unas pocas palabras reservadas por el momento:

  • tabla:  # Especifica que se debe crear una nueva tabla, con el nombre que sigue a continuación de los dos puntos
  • campo: # Especifica el nombre del campo y su tipo.
  • ucamp: # Especifica que es el ultimo campo de la tabla.
Tener en cuentas que tabla, campo y ucamp SI O SI deben estar seguidas de dos puntos ":"

En cuanto a los tipos de datos tenemos:

  • entero: Tipo de dato entero. :)
  • cadena: Tipo de dato String. Debe seguir a continuación la longitud de la cadena, en caso que no se especifique la longitud, se toma por defecto 50 caracteres.
  • real. Tipo de dato Real.
Para comprender un poco mas el uso del Framework, recomiendo ver estos dos videitos, que espero se entiendan.. :).. Si no lo logran ver bien, ponganlo en pantalla completa y mejorenle la calidad a 480p y lo verán perfectamente.

Video 1

Video 2

Para descargar el Ejecutable para Windows, pueden hacerlo desde el siguiente Link:

Descargar PyFrame

Espero que les guste, y que les sirva.. Cualquier comentario o sugerencia sera bienvenido..

Saludos y hasta la próxima.. 

martes, 30 de octubre de 2012

Frameworks (Teoria)

Los Frameworks suelen definirse como "Marcos de Trabajo", esta seria la definición prácticamente literal de la palabra Framework. De todas formas si bien a alguno que se encuentra en el tema de la informática,puede llegar a brindarle alguna pista con respecto a lo que en realidad son, al común denominador de la gente la definición "Marco de Trabajo" nada le dice. 

Para que todos lo entendamos, podemos decir que un Framework, no es ni mas ni menos que un programa al cual le faltan porciones que nosotros podemos completarlas para conseguir algun objetivo particular.

Alguna definiciones un poco mas formales que pueden encontrarse en la web son:

________

"En lo que respecta al desarrollo de software, un Framework suele verse como una estructura de soporte bien definida, en la cual otro proyecto software puede ser organizado y desarrollado."
________

“Un framework se puede considerar como una aplicación genérica incompleta y configurable a la que podemos añadirle las últimas piezas para construir una aplicación concreta. Los objetivos principales que persigue un framework son: acelerar el proceso de desarrollo, reutilizar código ya existente y promover buenas prácticas de desarrollo como el uso de patrones.”

La experiencia nos dice que siempre que vamos a desarrollar una aplicación informática, tendemos a normalizar y estructurar los datos de forma tal que podamos modelarlos, para hacer mas sencillo el almacenamiento y la recuperación de estos. Por lo general esa información estructurada suele convertirse en modelos que luego terminan siendo la Base de Datos del sistema que estamos desarrollando. Sin embargo, cuando de estructurar los archivos propios de cada desarrollador se trata, entramos en una zona en la cual nada esta claro y todo queda librado al azar y a las buenas practicas del propio desarrollador. La estructura de directorios, los nombres y estructura de los códigos fuentes, y los nombres y estructuras de los archivos de configuración, son algunas de las cosas que quedan a la "buenas de dios", cuando comenzamos un desarrollo. 
En la mayoría de los casos, cuando se comienza un desarrollo, se suele pensar que luego de haber definido las herramientas (lenguaje de programación, y motor de base de datos), ya tenemos casi todo resuelto, pero esto esta muy alejado de la realidad; En ese momento es justamente donde aparece toda esa incertidumbre producida por la falta de normalizacion y de estructuración de los componentes propios del desarrollo. 
Para solventar esta problemática es que existen los frameworks, ya que los mismos nos brindan una estructura ya probada y satisfactoria para resolver problemas de cierto dominio concreto. 

Los objetivos principales que persiguen los Frameworks son: 

  1. Acelerar el proceso de desarrollo.
  2. Fomentar la reutilizacion de código, y promover buenas practicas de programación, como el uso de patrones. 
Digamos que ambos objetivos están bastante relacionados, ya que el proceso de desarrollo se acelera debido a que mediante la utilización de un framework, se suele tener mucha de la programación de bajo nivel resuelta, por lo cual podemos centrarnos en programar la lógica propia del desarrollo particular que estamos llevando a cabo. 
Habitualmente los frameworks están intrínsecamente relacionados con un lenguaje de programación, ya que de esta forma es que consiguen mayor potencial. Por lo general los frameworks que no están desarrollados para un lenguaje de programación en particular, suelen resolver cuestiones mucho mas sencillas y básicas que aquellos que si lo están. 

La utilización de un framework tiene como ventajas:
  1. Velocidad de desarrollo: 
  2. Código optimizado
  3. Reducción de costos
  4. Estadarizacion y Convención en el código
También trae consigo algunas desventajas como pueden ser:
  1. Tiempo de aprendizaje
  2. Dependencia
  3. Falsa sensación de conocer el lenguaje
Las ventajas "velocidad de desarrollo" y "reducción de costo", van un poco de la mano, ya que al mejorar la velocidad de desarrollo gracias a la reutilizacion de código, se puede reducir la cantidad de trabajo, lo que reduce el tiempo y que es lo que en definitiva disminuye los costos. 
La ventaja de código optimizado esta dada mas que nada por la comunidad que da soporte al framework, sobre todo en frameworks grandes como puede ser por ejemplo "Symphony" o "Django", las comunidades que están detrás de estos desarrollos son enormes, por lo cual permanentemente se les van haciendo actualizaciones y mejoras.
Estadarizacion y Convención en el código, si bien son dos cualidades que pueden conseguirse sin la necesidad de utilizar un framework, podemos decir que la utilización de uno, nos obliga en cierto punto a seguir algunos lineamientos a la hora de desarrollar, lo que produce que cualquiera que conozca el framework y tome nuestro desarrollo, ya sea para hacerle mantenimiento o para ampliarlo, lo comprenda. 

De todas formas no todo es color de rosas en el mundo de los frameworks. Sobre todo en frameworks grandes y complejos, la curva de aprendizaje suele ser bastante empinada, lo cual es un tema a tener en cuenta a la hora de estimar tiempos de desarrollo. Cuando utilizamos un framework, normalmente en la jerga de la informática se dice que "Nos estamos casando con él", ya que una vez que comenzamos el desarrollo, es muy difícil migrarlo a otro framework sin tener que cambiar TODO el código escrito. Por ultimo y a la desventaja final que dice "Falsa sensación de conocer el lenguaje", a lo que me refiero es a que muchas veces se cree que por utilizar un framework, conocemos el lenguaje para el cual están desarrollado. Un ejemplo típico es cuando utilizamos por ejemplo JQuery, muchas veces creemos que por utilizar jQuery sabemos programar con JavaScript, pero esto no es asi... Como nota personal y por mi experiencia siempre aconsejo aprender a manejar el lenguaje de programación, antes de usar un framework complejo. 

Por ultimo algunas cositas que me gustaría comentar son:

Muchas veces se confunde lo que son los frameworks con las librerías o bibliotecas de un lenguaje. 
La diferencia fundamental entre los Frameworks y las librerías o bibliotecas es que cuando utilizamos las bibliotecas lo que estamos reutilizando es código, en cambio cuando utilizamos un framework, reutilizamos la arquitectura.

También he leído en la web que cuando alguien dice que esta utilizando su propio framework en realidad esta haciendo mal el trabajo. Según mi experiencia y esto es una apreciación personal, una persona, tranquilamente puede desarrollar su propio framework, para algún dominio concreto en el cual se encuentre suficientemente capacitado. Yo creo que los pasos para desarrollar un framework serian:

  1. Tener bastante experiencia en desarrollos de un dominio concreto, y haber encontrado alguna manera de desarrollarlos que te ha dado éxito en todos los casos. 
  2. Definir el dominio especifico. 
  3. Definir el lenguaje a utilizar. 
  4. Definir cuales son los pasos genéricos que realizamos cada vez que comenzamos un desarrollo del dominio especifico. 
  5. Ver si se pueden sistematizar dichos pasos genéricos. 
  6. Sistematizarlos.
En una próxima publicación pondré un ejemplo de un framwork que estuve haciendo en estos días, que se adapta perfectamente para la programación de aplicaciones pequeñas, con interfaz gráfica y Base de Datos. 
El framework es para Python, tiene como ORM sqlalchemy, motor de base de datos SQLite y la parte gráfica hecha con PyQT. Con esas cuatro herramientas, podemos hacer programas bastante complejos y en pocos minutos utilizando mi framework. 

Saludos y nos vemos en la proxima.