martes, 27 de septiembre de 2011

Upload de QPixmap a Php

Hoy tuve que enfrentarme a la tarea de subir una imagen desde un Programita en C++ a un Script en web de PHP.
Al inicio pensé que no seria complicado pero después de un rato me di cuenta que era la tarea era "infernal".
Mi primera opción fue usar CURL, pero despúes de varios intento fallidos me decline por QT.
Qt tiene una serie de clases para manejo de Network. Sin embargo la mayoría a quedado obsoleta dejando muy pocas en juego.
Al final me decidí por hacerlo con QNetworkAccessManager. Veamos código primero y despúes la explicación.

Prueba Conceptual:

Form en HTML

Enviar un nuevo archivo:

Codigo PHP para subir imagenes

$target_path = "uploads/";

$target_path = $target_path . basename( $_FILES['userfile']['name']); 

if(move_uploaded_file($_FILES['userfile']['tmp_name'], $target_path)) {
    echo "The file ".  basename( $_FILES['userfile']['name']). " has been uploaded";
} else{
    echo "There was an error uploading the file, please try again!";
}

Nota:
No mucho que explicar aca, un form que sube cualquier cosa. Esto se lo manda al PHP y lo salva en una carpeta de upload.

Ahora lo que intenso hacer es simular el request del browser con C++ con QT.

void UploadManager::upload(QString url, QPixmap img){
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)),
    this, SLOT(downloadFinished(QNetworkReply*)));
    QByteArray bytes;
    QBuffer buffer(&bytes);
    buffer.open(QIODevice::WriteOnly);
    img.save(&buffer, "PNG");
    QByteArray multipartform;
    QString crlf("\r\n");
    QString boundaryStr("---------------------------109074266748897678777839994");
    QString boundary="--"+boundaryStr+crlf;
    QString filename = "test.png";
    multipartform.append(boundary.toAscii());
    multipartform.append(QString("Content-Disposition: form-data; name=\"userfile\"; filename=\"" + filename + "\"" + crlf).toAscii());
    multipartform.append(QString("Content-Type: text/plain" + crlf + crlf).toAscii());
    multipartform.append(bytes);
    multipartform.append(QString(crlf + "--" + boundaryStr + "--" + crlf).toAscii());
    QNetworkRequest request;
    request.setUrl(QUrl(QString("http://127.0.0.1/PruebasConceptuales/upload/subearchivo.php")));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundaryStr);
    manager->post(request, multipartform);
}

Explicación:

Básicamente, lo que hacemos es construir el Request que usa Firefox. Se sabe que cuando se va a subir una imagen el Archivo pasa por un proceso de Base64. Curiosamente el QPixmap simplemente lo convierto en un flujo de Bits (lineas 5 - 8). Y con eso basta para subir. Despúes seguidamente hacemos otro Array de Bits con el cual empezamos a meter todos los datos para simular el post (Lineas 8 -18). Creamos un QNetworkRequest y le decimos al QNetworkAccessManager que use el request y que le pase todos los datos con manager->post(request, multipartform);

Cualquier consulta no duden en comentar :P

lunes, 26 de septiembre de 2011

Kde - Dolphin - Symbolik Link Gui

Hoy saque el rato para hacer un par de Desktop entries que me permitirán hacer los symbolic linnk.

Ya saben el clasico:

ln -s <Origen> <destino>

La cuestión es que por razones meramente laborales, últimamente he tenido que ejecutar ese condenado comando ya varias veces. No es difícil simplemente es medio cansado escribir esas enormes direcciones.

Buscando en el repo y "googleando" tope con tan mala suerte que no encontré ningún GUI. Curiosamente hay un proyecto de symbolic link para "Guindos". Aqui le pueden echar una mirada.

Bueno entonces, me decidí a hacer mi propia versión del asunto. En vista de que un programita en C++ cumpliría mis expectativas, pensé que no seria adecuado ya que estar buscando dos path con un FileChooser es bastante irritante. Sin embargo era mejor que escribir los path a mano. (Vean kompare como ejemplo)

Entonces la inspiración me llego con Dolphin, si pudiera usar el menu contextual para generar orígenes y destinos. Hasta el momento no se como hacer plugin para Dolphin (No se si se puede) pero si había usado los desktop entries para expandir las opciones del menú contextual.

Bueno, entonces manos a la obra.

Como funciona?

Desktop entrie es un archivo especial en los escritorios X definido por FreeDesktop. Es un simple archivo de texto que define reglas y la ejecución de comandos.

Para que funcionen en KDE se puede poner en dos lugares:

/usr/share/kde4/services/ServiceMenus/

/home/<User>/.kde/share/kde4/services/

Y con solo ponerlos ahí basta. Cuando Dolphin refresque estos entries agregara el comportamiento definido en los menus contextuales.

Yo necesitaba habilitar la opción de origen a cualquier cosa, archivos, carpetas.
Entonces la definición fue asi:


[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory,all/all,all/allfiles
X-KDE-Submenu=Symbolic Links
X-KDE-AuthorizeAction=shell_access
Actions=lnorigin;

[Desktop Action lnorigin]
Name=Origin
Icon=/opt/resources/SymboliclinkOrigin.png
Exec=bash /opt/scripts/services/lnorigin.sh %f

El script simplemente salva %f  en un archvio temporal en home:

#!/bin/bash
echo $1 > /home/koza/.lnorigin.txt

El asunto con el Destino fue diferente. El menú contextual de Dolphin solo debía mostrar la opción cuando se estuviera apuntando a una carpeta. Esto se debe a que en la carpeta me va a pedir el nombre (Utilice el comando KDialog). Mi definición y el script que hace el truco por abajo fue así:

[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory
X-KDE-Submenu=Symbolic Links
X-KDE-AuthorizeAction=shell_access
Actions=lndesteny;

[Desktop Action lndesteny]
Name=Destiny
Icon=/opt/resources/SymboliclinkDesteny.png
Exec=bash /opt/scripts/services/lndesteny.sh %f


#!/bin/bash
path=$1
if [ -f /home/koza/.lnorigin.txt ]
then
    name=$(kdialog --title "Destiny Name" --inputbox "What name do you want?")
    ln -s `cat /home/koza/.lnorigin.txt` $1/$name
else
    kdialog --error "Destiny is not setted"
fi

Notas:
Queda de mas decir que la ubicación de la imagen, la ubicación donde se va a correr el script y otras cosas deben ser ajustados.

PD: Los archivos desktop entries pueden tener cualquier nombre pero con extensión .desktop.

Si tienen problemas comenten abajo y si esto es como muy solicitado puedo hacerme un script de instalación.

Actualización:

Descubri que la manera mas rapida para refrescar los desktop entries (inclusive imagenes) es atravez del comando siguente:

#!/bin/bash
kbuildsycoca4

domingo, 25 de septiembre de 2011

Qt + manipulación de imágenes

Como muchos de mis "seguidores" saben. Yo adoro C++ y QT cuando a programación en linux respecta. La cancha esta bastante clara para mi.

1. Qt tiene mejor documentación ( assistant - Programa de ayuda)
2. Es nativo en c++
3. El 90% de todo tiene ejemplos en codigo
4. El IDE QDevelop es una maravilla.

En fin muchas cosas que algún día escribiré una entrada sobre por que QT es "chiva".Sin embargo no opaca GTK aunque a titulo personal no me gusta.

Hoy he estado haciendo pruebas conceptuales (Pequeños programas) para desarrollar un programa para mi mama.

En mi viaje me encontré con la manipulación de imagen.
Ya había usado manipulación de imágenes anteriormente en QT, algo bastante sencillo pero me daba la idea de por donde buscar. Además en lo de manipulación de imágenes se respecta yo tengo mucha experiencia en Java.

Qt tiene varios clases de manipulación de imágenes para distintos niveles.

QImage:
Esta provee de un set de métodos para manipulación a nivel de Pixel.

QImage ImageDialog::verticalrotation(QImage source_image){
    QImage new_image(source_image.width(), source_image.height(), source_image.format());
    int height_subtraction = source_image.height() - 1;
    for(int x = 0; x < source_image.width(); ++x)
        for(int y = 0; y < source_image.height(); ++y)
            new_image.setPixel(x, height_subtraction - y, source_image.pixel(x, y));
    return new_image;
}
QPixmap:
Esta provee una serie de métodos para realizar transformación de nivel mas alto. Puede ser rotaciones, dimensionar, cortar partes de images, entre otras.
//Corta una sección de una imagen más grande 
QPixmap test = QPixmap(QString::fromUtf8("/home/koza/47411-bigthumbnail.jpg"));
QPixmap chunk = test.copy(10,10,100,100);
label->setPixmap(chunk);
QPainter:
Esta clase provee manipulación de utilitarios. Metodos como dibujar texto, eclipces, rectangulos. Es muy semejante a Ghaphics2D de java.
QPixmap pic(QPixmap::fromMimeSource( "camera.png" ));
QPainter paint;
paint.begin(&pic);
paint.setPen( Qt::blue );
paint.drawText( rect(), AlignCenter, string);
paint.end(); 
mPixLbl->setPixmap(pic);

Convertir de un tipo a otro es relativamente sencillo.  No voy a poner los detalles acá. Sin embargo es bueno comentar que existe una serie de clases para manipulación de imágenes.

Solo resta decir que escoger la clase adecuada depende de lo que se quiera programar.

domingo, 18 de septiembre de 2011

Eyeos -> Unable to search all data matching $transferObject from database

Todo empezó hablando con un compañero del trabajo que es tan entusiasta en programación y de tema en tema empezamos a "fachentiar" sobre las famosas cloud. Fue donde le comente un poco sobre este sistema (EyeOs). Es muy impresionante y open source. De hecho me encanta el Api. Es un engine muy curioso el que desarrollaron.

En la oficina yo uso KDE 4. El problema es que KDE viene por defecto con Mysql, dando problemas cuando tienes que usarlo para otra aplicación como WordPress o EyeOS. Para mayores detalles se puede acceder aca. En la instalación es sencillo, simplemente le establecemos el socket Unix de la siguiente forma:

:home/koza/.local/share/akonadi/socket-sabrina/mysql

Pero cuando tratas de crear una cuenta veras el siguiente problema:

Unable to search all data matching $transferObject from database

Esto se debe a un problema con la conexión a la base de datos de mysql.

Pero si yo veo el esquema de la base de datos con el GUI de mysql?
Si es verdad. La instalación se lleva a cabo de forma exitosa. Pero la instalación usa un código muy diferente al de la aplicación para su funcionamiento productivo. Los scripts de instalación son basicamente desechados una vez la aplicación esta configurada.

Entonces me puse a travesear el código. Muy claro, muy limpio, soy un fan de los desarrolladores de esta aplicación. En mi investigación el script GenericDao.php en el método getConnection esta la magia.
Se implemento usando la clase PDO. (Esto es algo generico de PHP para ecapsular las conexiones a las bases de datos). Entonces el truco es más sencillo de lo que creen. Basta simplemente con abrir settings.php. En la definición de la variable SQL_CONNECTIONSTRING hay que agregar la declaración del unix_socket al string de conexión.


define('SQL_CONNECTIONSTRING', 'mysql:host=localhost;dbname=eyeos;unix_socket=<Ubicación de socket>');

Este seria para mi caso:

define('SQL_CONNECTIONSTRING', 'mysql:host=localhost;dbname=eyeos;unix_socket=/home/koza/.local/share/akonadi/socket-sabrina/mysql.socket'); 

Espero les sirva. Cualquier consulta comenten :P

sábado, 17 de septiembre de 2011

Un extraño en tierras ajenas. Freedom software day sarapiqui

En estas fechas se celebra el Freedom Software Day. Como buen Geek, simpatizo con la causa y me di a la tarea de incorporarme a las actividades en las que la Universidad Nacional pensaba desenvolverse. La experiencia de hoy a sido enriquecedora pero algo extraña. Todo empezó cuando la Red costarricense de software libre. Grupo al que formo "parte" estaban solicitando ayuda para hacer estantes y charlas para la cede de Sarapiqui. Me ofrecí para ambas actividades. Mi Stands estaría basada en juegos libres y mi charla en entornos de programación en Linux. Quiero abrir un paréntesis para mencionar que el el año pasado colabore con la frase "voy a ayudar" en lo que me pusieran a hacer. Me lleve una amarga experiencia a la cual no quiero tomar remembranza en este momento. Este año dije "Colaborare pero sera en algo que realmente me motive".

En vista que llevaría todo el equipo de juegos eso consistía en; el teclado gammer, el joysitick, los parlantes, la compu. Lo único que solicite era el "RAY". Jennifer Vargaz se ofreció en llevarme. (Mil gracias de paso). Dos chicas más serian mis compañeras de viaje. Andrea Torres y Diana Rodríguez. Yo sabía que Andrea Torres si tiene trascendencia en esto del software libre. Anteriormente la había "conocido" en una charla sobre SSH. Algo básica pero interesante.
Desgraciadamente de las otras dos muchachas no tenía ni idea.

En un principio ir tan largo con completas desconocidas me aterraba completamente. Incluso la noche anterior, necesite tomarme un te de tilo bien cargado para poder conciliar el sueño. Era algo completamente loco, no sabía que esperar, no tenía amistad con ninguna de ellas. Lo único que tenía era un conjunto de referencias, un par de fotos y actividades en las que habían participado donde la la documentación seguía siendo disponible por medio del Internet.

El día de la actividad me desperté alrededor de las 5:15am. No quería llegar tarde. Me levante inspirado en preparar todo lo que necesitaba llegar. Cuando mi equipo estaba listo para el viaje, solicite un taxi. Me permitió llegar a la Universidad nacional alrededor de las 6:40am. Tenia suficiente tiempo para esperar con las chicas que viajaría. Ya me pito Jennifer a la distancia. Donde ya pude reconocer a Andrea Torres (Una cara no la olvido nunca). Me dirigí donde ellas, salude, acomode mi equipo y me senté un poco nervioso en el asiento de atrás. Empezamos a hablar un poco, realmente no hable mucho. Me dio la impresión que ellas se conocían de muchos año. Hablaban de actividades, recuentros de la U, actividades de la red, que hacer en sus oficinas. No se tornaron muy interesadas en mi la verdad. Sin embargo el estar callado escuchando con interesantes me sienta muy bien. Desṕues de un viaje relativamente corto. Llegamos al campus de la UNA de sarapiqui.

Llegando a la UNA fue la primera vez que vi a Gabriela Mejias. La que fue mi contacto directo para llevar acabo la actividad en la Cede. La Universidad de Sarapiqui es muy chiva, tiene paisajes boscosos en sus alrededores. El lugar es como ver Bijagua de Alajuela. Un lugar "Rural" muy agradable, pero nada como mi caliente Guanacaste. (:P). Ya fui a desayunar con las chicas.
Poco tiempo después era hora de montar el stand de juegos. Me asignaron a Diego. Un estudiante de informática que seria mi mano derecha. Tengo que admitir que el Stand fue todo un éxito. Los asistentes se tornaron muy interesados. Entre los juegos que logre que jugaran estuvo; Openarena, Gltron, Super Tux, Super Tux Car y World. Los involucrados llegaban, reían, se divertían, hablaban un poco conmigo, copiaban los juegos y comentaban. Para mi lo mas sobresaliente fue una chiquita de alredor de unos 7 - 8 años que se acerco. Adrea Torres le cedió el control (Joystick). La niña gozaba con Super Tux. Realmente fue muy chistoso verlo. De repente el padre se acerco y me pregunto sobre que tan difícil era configurar un joystick y hablamos un poco al respecto.

Después de todo el "despelote" que fue el estante de juegos libres. Me toco la charla de programación. La charla era muy pesada, pero se llevo acabo en el tiempo proviso (1 hora). A todos les dije que los ejemplos que viéramos se los podía copiar una vez finalizada la charla. Los temas que logre abarcar fueron; Librerías, Binarios, g++, Gui, java y php. Fue algo muy relámpago, pero dejaba la idea de como empezar a programar. Lo que mas me dolió fue que pase semanas preparando los ejemplos con comentarios, notas y todo lo necesario. Al final solo uno de todos los 17 asistentes me pidió el correo. OJALA que me solicite el material. (:s)

Aquí les dejo el material por si quieren ver mi trabajo.

Por ultimo, después de las fotos, los besos y los abrazos. Me despedí de la cede de Sarapiqui y su gente. Muy agradecido por que todos fueron tan amables. Con una sensación de satisfacción. Diciendo UNA "Gracias por todo lo que me diste". Espero haberte retribuido un poquito el día de hoy.

Nos emprendimos en nuestro viaje de vuelta. Un poco incomodo por reparaciones en la carretera y la neblina. Cuando al fin llegamos a Heredia. Pasamos a comer a un restaurante, donde tuve la oportunidad de compartir una ultima vez con las chicas. Mis ultimas palabras de esta entraba se las quiero dedicar a ellas. Infinitamente agradecido; por acogerme en el viaje, su amabilidad mostrada, su tiempo y sus buenas intenciones. Considerado como un desconocido lograron hacerme sentir muy cómodo. Se que es esta vida nada sucede como deseábamos, como suponíamos, ni como teníamos previsto. Pero me siento muy afortunado en haberlas conocido hoy. Todas ustedes tienen mis respetos, besos y abrazos. Espero volver a vernos pronto...

viernes, 16 de septiembre de 2011

Teclados mecanicos y yo!!!

Hoy ha llegado el ultimo de mis teclados mecánicos. Que emoción :P.  Elegí uno que realmente fuera silencioso para la oficina. Pues ya había comprado uno para la casa. Estos teclados tiene la fama de que son para toda la vida. Para ser honesto eso espero. He invertido alrededor de unos $100 por teclado. Para la casa, en vista de que estoy a la espera de diablo 3 y jugando Starctraft elegí el Black Widow de Razor. Este teclado viene equipado con los Cherry Mx Blue. Son bastante ruidosos. Pero son excelentes para teclear. Vienen con 5 MacroKeys además de iluminación por tecla. Pesa 3 Kilos con todo y caja. Hasta el momento estoy sin quejas, para jugar son excelentes y en mi caso para escribir código son estupendos.
En la oficina si presento un reto interesante. El 70% de mi tiempo estoy en el trabajo, sin embargo necesitaba algo que fuera silencio y que a la vez tuviera la delicadeza de un teclado mecánico. Quiero dejar por sentado el hecho que a mi me preocupa la ergonomia. Yo escribo mucho. Después de cierto tiempo escribiendo me empiezan a dolor las manos. Por eso la idea de comprar teclado mecánicos fue la solución a mis problemas. Al final me decide (supervisado con un amigo) por un Filco Majestouch 2. Estos vienen con Cherry Mx Brown. Se siente un poco extraño al teclado que tengo en casa. Pero es muy cómodo, además adquirí un gel de goma para descansar la mano. Hasta el momento no tengo quejas tampoco. No hace mucho ruido y podría pasar como un teclado común y corriente. No tiene iluminación, no tiene macros. Pero su valor esta a la hora de escribir. QUE MARAVILLA...

Ya había tenido la experiencia de un teclado mecánico anteriormente. El amigo que me ayudo a elegir el teclado es tan adicto como yo a Star Craft II. El fue el primero en comprar el teclado mecánico ya que son súper famosos entre los jugadores profesionales de Star Craft II. Hace cierto tiempo atrás lo llevo a una reunión de amigos y me permitió usarlo para un mach. Enamorado a primer touch... (Cuantas veces han escuchado decir eso???)

Tal vez sea cierto que los teclado mecánicos con muy caros, también dicen que no valen su precio. Pero hasta el momento no tengo ningún problema con ellos. Yo programo mucho y me encanta escribir en el blog. Para mis fines son excelentes. Los teclados de goma convencionales tienden a gastarse, a cansar los dedos y después de un tiempo pueden producir graves problemas en la salud. No puedo hablar mucho porque llevo un par de días con estos teclado, pero a mi criterio me llevare bien con ellos hasta que expiren su vida útil y parece que moriría escribiendo antes que eso pase.

domingo, 11 de septiembre de 2011

Kubuntu, Php y Mysql

Me imagino que a muchos les ha pasado el siguente error:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld

Y de verdad que da mucha colera :P. Y si usamos sudo la cosa se pone peor. Lo que da mas chicha es que este error es muy típico para KDE.
Para ponerlos en contexto resulta que mysql ya viene por defecto en KDE. Lo usa el programita Akonadi. La verdad no voy a hablar mucho sobre el. Simplemente queria aclararlo. Entonces el peor error en KDE si quieres mysql para programar es teclear:

sudo apt-get install mysql

Porque entonces la cosa se enreda mas y el resultado sera dos mysql instalados y ninguno operacional. Entonces por favor NO LO HAGAS.

Lo que puedes hacer es usar la instancia que ya existe de Mysql que Akonadi necesita. Resulta que ya existe un socket por defecto. Es este amigo de aca.

/home/<USER>/.local/share/akonadi/socket-sabrina/mysql.socket


Entonces vamos a levantar el servicio de mysql con el siguente comando.

mysql --socket=/home/koza/.local/share/akonadi/socket-sabrina/mysql.socket

Nota: Recuerden dejar la terminal abierta, si la cierran despues de unos minutos el servicio bajara.

Ahora bien. Podemos hacer un script pequeñito para realizar la prueba.

//No se necesita poner la extencion .socket is se pone los (:) al inicio del path
$link = mysql_connect(':home/koza/.local/share/akonadi/socket-sabrina/mysql', 'koza', '');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);


Con eso debería bastar. 

Pero por si los fallos, acá esta un par de tips que se pueden usar:

Asegúrese de que Akonadi este funcionando. Puede usar el el programa "Configuracion de Akonadi". Y en la pestana de "Configuracion del servidor" bajar el servicio y volverlo a subir.

Si es un caso en el que da problemas de permitos. Lo que se puede hacer ir al archivo Httpd.conf del Apache y modificar la linea:

User nobody por User <USER>

AEM hablemos del arquetipo 11

Cuando creamos un proyecto con AEM. Siempre es importante saber que arquetipo estamos usando. Pues esto me determinara que source, herramien...