La embriagadez del emprendedor

Tarde o temprano el emprendedor se emborracha. Se emborracha por su idea, afrontando la realidad de una forma irracional, basándose en las emociones. Ve la realidad desde un prisma diferente.

Debemos intentar,  siempre, pensar en frío, que no te pueda la visceralidad. Es peligroso dejarse llevar por las emociones. Sé paciente, pero realista. No esperes sentado, actúa. Muévete, sé dinámico, que te conozcan. Pero tienes que analizar siempre en que momento estás. Quizás no sea tan bueno. Dicen que en EEUU las derrotas están bien valoradas, es experiencia. Recuerda que estás en España y te sentirás humillado. Así que no procrastines el final y reconócelo antes de que te enfangues hasta el cuello. Qué no te desmotive estar en España, eso es algo circunstancial. Piensa en grande y actúa en pequeño. No busques financiación o grandes millonadas, la gente no lo regala.

Si buscas autoempleo no montes una empresa, hazte freelance. Si lo que buscas es montar una gran empresa, localiza tu objetivo y ten claros tus recursos. ¿Cuáles son?.

Todo tiene un principio y un final. Antes o después todo termina, nada es infinito y tu empresa por supuesto, tampoco. Sólo un 1o% de las empresas que se constituyen llegan al tercer año de vida. Y sin contar una parte de los que llegan a base de sufrimiento y sin alcanzar el break-even. Es muy difícil que tu empresa funcione, tienes que ser constante, paciente e inteligente.

La organización

La organización se define como “preparar una cosa pensando y cuidando todos sus detalles.”. Os voy a contar como gestiono mi tiempo con las herramientas actuales.
Una de las perdiciones del empredendor es la gestión del tiempo, en mi casa la lista de tareas me abrumaba de tal forma que no era capaz de afrontarla. Pero un día decidí gestionar de forma eficiente el tiempo y comence a quitarme tareas a cuentagotas, pero con el tiempo se redució notablemente.

La gestión de mi tiempo la realizo mediante herramientas grautitas online para Ubuntu, Android y web online. Ahora anotaré cuáles son:

Para gestionar los eventos y reuniones uso google Calendar para Android y Web Online. La herramienta te permite separar los eventos por calendarios y tenerlo todo sincronizado.

Para la gestión de tareas a realizar, ordenado por prioridades, utilizo Google Task con taskos en android. Esta herramienta gestionan lo que en programación se llama TODO (a hacer). También te permite crear listas separando las tareas por temáticas.

Para realizar las tareas de forma eficiente utilizo la herramienta timer-applet(para instalar:sudo apt-get install timer-applet) de Ubuntu que me permite temporizar el trabajo.

Para la gestión de proyectos utilizo una herramienta conocida como collabtive y que permite trabajar de forma colaborativa. La herramienta es gratuita.

Y para conocer el trabajo que he realizado o anotación en reuniones y llamadas utilizo una herramienta muy útil y muy novedosa: libreta y boli.

Otro de los consejos es sincronizar cada 30 minutos la visualización del correo electrónico.

Bueno espero que os sirva mi forma de trabajar.

API codeigniter

La API esta compuesta por dos librerias: User(se encarga de la autentificación) y Api (que sería el core).

User
User es la libreria encargada de la autenticación. La autenticación se basa en un hash construido por la clave publica y el método al que se llama, y tiene como semilla la clave privada que sólo es conocida por el cliente y el server. La clave pública actúa como identificador de usuario. En este caso he reducido la clase para que sea más entendible.

El hash se genera de la siguiente forma.

hash_hmac("md5",CLAVE_PUBLICA.METODO,CLAVE_PRIVADA)
<?php
class CI_User{

    var $CI;
    var $id = false;
    var $mail = false;
    var $key = array('consumer_public'=>'123','consumer_private'=>'456789');		

    function CI_User() {

        $this->CI = & get_instance();

    }

    function apilogin(){

         if ($this->authapi()) {
           return true;

        } else {

            header('WWW-Authenticate: Basic realm="API eCamina"');
            header('HTTP/1.0 401 Unauthorized');
            echo "Yo can't access. You need auth";
            exit;

        }

    }

    function authapi(){

        if(!isset($_SERVER['PHP_AUTH_USER'])||!isset($_SERVER['PHP_AUTH_PW'])){

           return false;

        }

        $user = $_SERVER['PHP_AUTH_USER'];
        $pass = $_SERVER['PHP_AUTH_PW'];

        if(hash_hmac("md5",$user.$this->CI->uri->segment(2),$this->key['consumer_private']) == $_SERVER['PHP_AUTH_PW']){

            return true;
        }else{
	    return false;
	} 

    }

}

?>

La libreria API recibe los siguientes parametros en la carga:

$list = array('item'=>array('name'=>'roberto','lastanme'=>'Rubio','year'=>'27'),'example'=>array('example'=>'1','example'=>'12125'));

        $config['data'] = $list;
        $config['name'] = MÉTODO;
        $config['error'] = $error;//Boolean;
        $config['type'] = $this->_type(4);//Tipo de los datos a devolver // json o XML.

El array $config es pasado en la carga de la libreria load. A continuación anoto el código de la librería. Básicamente la librería recibe $data que es un array asociativo con los datos a formatear para la salida por pantalla y que depende de los parámetros como type y error. El dato name del array config hace referencia al método que necesitará la autentificación en la librería user.

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class CI_Api {

    var $data = array();
    var $error = false;
    var $type = 'xml';
    var $typee = array('json', 'xml');
    private $CI;

    function CI_Api($param = false) {
        $data = array();
        $error = true;
        $type = 'xml';
        $name = 'WebService';

        foreach ($param as $key => $val) {

            switch ($key) {
                case 'data': $data = $val;
                    break;
                case 'error': $error = $val;
                    break;
                case 'type': $type = $val;
                    break;
                case 'name': $name = $val;
            }
        }

        $this->name = $name;
        //comprobamos si existe algún error desde la declaración
        $this->error = $error;

        //comprobamos si el array esta vacio
        if (!$this->_set_data($data)) {
            $this->error = true;
        }

        if (!$this->_set_type($type)) {
            $this->error = true;
        }

        if ($this->error) {

            $this->data = array('Error' => 'Error: not found');
        }

        $this->CI = &get_instance();
    }

    function _set_data($value) {

        $ok = false;
        if (count($value) > 0) {
            $this->data = $value;
            $ok = true;
        }

        return $ok;
    }

    //Seteamos el tipò de datos
    function _set_type($value) {

        //comprobamos si el valor esta dentro de los tipos permitidos y guardamos en type
        $ok = false;
        foreach ($this->typee as $t) {
            if ($t == strtolower($value)) {
                $this->type = $value;
                $ok = true;
                break;
            }
        }

        return $ok;
    }

    //devolvemos el error
    function _get_error() {
        return $this->error;
    }

    //devolvemos el tipo pedido
    function _get_type() {
        return $this->type;
    }

    function _get_data() {
        return $this->data;
    }

    function _format() {
        $method = "_get_" . $this->type;
        $this->$method();
    }

    function _get_xml() {

        $xml = new ArrayToXML();
        header('Content-type: text/xml');
        echo $xml->toXml($this->data,$this->name);
    }

    function _get_json() {

        $this->CI->load->library("json");
        header('Content-type: application/json');
        echo json_encode($this->data);
    }

    function get() {

        $this->_format();
    }

}

class ArrayToXML { 

    private $Xml = ''; 

    function __construct() {
    } 

    public function toXml($array, $root = 'data', $numeric_identifier = 'nod'){ 

        $this->Xml .= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
        //$this->Xml .= "<".$root.">\n";
        $this->Xml .= $this->build_xml_tree($array, $numeric_identifier);
        //$this->Xml .= "</".$root.">\n"; 

        return $this->Xml; 

    } 

    public function toXml_echo($array, $root = 'data', $numeric_identifier = 'nod'){ 

        $this->toXml($array, $root, $numeric_identifier);
        echo $this->Xml; 

    } 

    private function build_xml_tree($array, $numeric_identifier){ 

        if(is_array($array)){ 

            $keys = array_keys($array); 

            for($i = 0; $i < sizeof($keys); $i++){ 

                $tag = $keys[$i]; 

                if(is_numeric($tag)){ 

                    $tag = $numeric_identifier; 

                } 

                $this->Xml .= "\t"."<".$tag.">\n"; 

                    $this->build_xml_tree($array[$keys[$i]], $numeric_identifier); 

                $this->Xml .= "\t"."</".$tag.">\n"; 

            } 

        } else if(!empty($array)) {  

            if( $this->checkForHtml($array) ){
                $array = '<![CDATA['.$array.']]>';
            } 

            $this->Xml .= "\t" .$array. "\n"; 

        } else { 

            return false; 

        } 

    } 

    private function checkForHtml($string){ 

        if( strlen($string) != strlen(strip_tags($string)) ){
            return true;
        }
        return false; 

    } 

} ?>

Reflection ingeniería inversa

¿Qué es Reflection?
Reflection es un paradigma de programación que permite conocer como esta construida las clases del código que se esta ejecutanda(ingeniería inversa). PHP tiene una libreria conocida como Reflection(originales!).

Caso de Uso

Imaginate que tenemos una clase cargada tal que así:

class Prueba{
public function saluda(){
return "hola";
}

public function despedida(){
return "adios";
}
}

Una forma de hacerlo sería abrir el fichero donde contenemos la clase y parsearlo para obtener sus métodos pero esto es poco elegante y puede que nos de más de un dolor de cabeza sin contar con cambios en las clases.

Con Reflection podríamos realizar las siguiente lectura:

  $class = new ReflectionClass("Prueba");
$metodos=$class-&gt;getMethods(); // $metodo contendrá un array con los métodos de nuestra clase.

Ojo tendríamos que tener cargado la clase en nuestra clase para hacer uso de ella. Puedes utilizar el método require();

Librería para implentar client XMPP

Estaba desarrollado un chat para el helpdesk de la empresa y empecé a buscar script PHP de chats para la implementación dentro de la aplicación. Después analicé mi necesidades y comprendí lo improductivo de tener una aplicación web para el contacto con el usuario. Yo soy usuario de gtalk así que me decidí por implementar un helpdesk que interactuara con Gtalk y que los mensajes del usuario se remitieran a mi usuario. Buscando encontré esta interesante librería para gestionar comunicación mediante el protocolo XMPP.  Este protocolo es el más extendido por la mayoría de aplicaciones de mensajería instantánea así que si no te convence trabajar con gtalk puedes utilizarla para muchos otros(facebook, ICQ, MSN…) o  incluso  implantar en un server XMPP.

Comprobar mail en PHP

Está función la encontré por internet hace ya un tiempo y la suelo utlizar en los proyectos dentro de algún helper. Lo dejo por que me servirá, seguro, dentro de algún tiempo.

function _comprobar_email($email){
$mail_correcto = 0;
//compruebo unas cosas primeras
if ((strlen($email) >= 6) && (substr_count($email,”@”) == 1) && (substr($email,0,1) != “@”) && (substr($email,strlen($email)-1,1) != “@”)){
if ((!strstr($email,”‘”)) && (!strstr($email,”\”")) && (!strstr($email,”\\”)) && (!strstr($email,”\$”)) && (!strstr($email,” “))) {
//miro si tiene caracter .
if (substr_count($email,”.”)>= 1){
//obtengo la terminacion del dominio
$term_dom = substr(strrchr ($email, ‘.’),1);
//compruebo que la terminación del dominio sea correcta
if (strlen($term_dom)>1 && strlen($term_dom)<5 && (!strstr($term_dom,"@")) ){
//compruebo que lo de antes del dominio sea correcto
$antes_dom = substr($email,0,strlen($email) - strlen($term_dom) - 1);
$caracter_ult = substr($antes_dom,strlen($antes_dom)-1,1);
if ($caracter_ult != "@" && $caracter_ult != "."){
$mail_correcto = 1;
}
}
}
}
}
if ($mail_correcto)
return 1;
else
return 0;
}

links how do to make a API’s?

Autenticación oAuth
http://code.google.com/p/oauth-php/
http://php.net/manual/en/book.oauth.php
http://oauth.net/code/

Tutoriales para la API
http://particletree.com/features/how-to-add-an-api-to-your-web-service/
http://blog.realmofzod.com/blog/2009/05/06/implement-a-rest-api-with-the-zend-framework/
http://jasonirwin.ca/2009/05/24/simple-api/
http://www.recessframework.org/page/towards-restful-php-5-basic-tips
http://www.gen-x-design.com/archives/making-restful-requests-in-php/
http://www.gen-x-design.com/archives/create-a-rest-api-with-php/
adlemons

Especulación en los dominios

Hace unos días estuve negociando, vía telefónica, la adquisición de un dominio muy interesante y que recibe mucha tráfico natural, que me venía como anillo al dedo a un proyecto que estoy creando poco a poco.

Pues bien el hombre, no estaba interesado ni en vender ni en explotar ni en participar en nada que tuviera que ver con ese dominio. Una forma muy fácil de cerrar una negociación.

Bueno pues pienso, que los dominios, al igual que las marcas, deben de explotarse. Debería existir un órgano que fuera el encargado de regular, teniendo potestad para decidir cuando un comprador de dominios está realizando este tipo de actividad, que por otro lado es otro de los problemas del sistema actual.

Ataques DDos

DDOS es una ataque de denegación de servicio (de las siglas en inglés Denial of Service). Hay muchas formas de hacer caer un servidor. La forma más utilizada es consumir su ancho de banda. Se consigue enviando peticiones http desde diferentes host produciendo un cuello de botella en la web reletizandola o echandola, directamente, abajo la conexión.

Estos días WIkileaks está sufriendo ataques de DDos y algunos servicios como PAYPAL, amazon, Visa, Mastercard… están negando la utilización de sus servicios, así que una parte de la sociedad indignada por lo sucedido están desafiandoles produciendo un ataque masivo a estos servicios.

Pensando en ello me di cuenta que era bastante más sencillo de lo que parece realizarun ataque masivo. Ejecutas un Shell script haciendo peticiones de forma abusiva a una IP(o domain) desde diferentes puntos.

Me acabo escribir hacer peticiones de forma recursiva a una IP:

#!/bin/sh

while [ 1 ]
do
curl //Aqui la IP a donde vayais a lanzar el ataque
done
exit 0

Se guarda en un fichero .so y se ejecuta en terminal como ./nombre del fichero . Sencillo ¿no?